When there is an List<Person>
, is there a possibility of getting List of all person.getName()
out of that?
Is there an prepared call for that, or do I have to write an foreach loop like:
List<Person> personList = new ArrayList<Person>();
List<String> namesList = new ArrayList<String>();
for(Person person : personList){
namesList.add(personList.getName());
}
Java 8 and above:
List<String> namesList = personList.stream()
.map(Person::getName)
.collect(Collectors.toList());
If you need to make sure you get an ArrayList
as a result, you have to change the last line to:
...
.collect(Collectors.toCollection(ArrayList::new));
Java 7 and below:
The standard collection API prior to Java 8 has no support for such transformation. You'll have to write a loop (or wrap it in some "map" function of your own), unless you turn to some fancier collection API / extension.
(The lines in your Java snippet are exactly the lines I would use.)
In Apache Commons, you could use CollectionUtils.collect
and a Transformer
In Guava, you could use the Lists.transform
method.
You might have done this but for others
using Java 1.8
List<String> namesList = personList.stream().map(p -> p.getName()).collect(Collectors.toList());
Try this
Collection<String> names = CollectionUtils.collect(personList, TransformerUtils.invokerTransformer("getName"));
Use apache commons collection api.
I think you will always need to do that. But if you will always need such things, then I would suggest to make another class, for example call it People
where personList
is a variable.
Something like this:
class People{
List<Person> personList;
//Getters and Setters
//Special getters
public List<string> getPeopleNames(){
//implement your method here
}
public List<Long> getPeopleAges(){
//get all people ages here
}
}
In this case you will need to call one getter only each time.
Not tested but this is the idea:
public static <T, Q> List<T> getAttributeList(List list, Class<? extends Q> clazz, String attribute)
{
List<T> attrList= new ArrayList<T>();
attribute = attribute.charAt(0).toUpperCase() + attribute.substring(1);
String methodName = "get"+attribute;
for(Object obj: personList){
T aux = (T)clazz.getDeclaredMethod(methodName, new Class[0]).invoke(obj, new Object[0]);
attrList.add(aux);
}
}
take a look at http://code.google.com/p/lambdaj/ - there is LINQ equivalent for Java. Using it won't avoid iterating all over items but the code would be more compressed.
You will have to loop through and access each objects getName()
.
Maybe guava can do something fancy ...
There is no other way to do this in Java than the one you suggested, at least as long as you are sticking with the standard Java Collection API.
I have been wishing for something like this for a long time... Especially since I tasted the sweet freedom of Ruby, which has wonderful things like collect and select working with closures.