Reputation: 4453
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());
}
Upvotes: 69
Views: 147843
Reputation: 420951
Java 8 and above:
List<String> namesList = personList.stream()
.map(Person::getName)
.collect(Collectors.toList());
In Java 16+ you can end it with .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.
Upvotes: 138
Reputation: 1464
You might have done this but for others
using Java 1.8
List<String> namesList = personList.stream().map(p -> p.getName()).collect(Collectors.toList());
Upvotes: 17
Reputation: 487
Try this
Collection<String> names = CollectionUtils.collect(personList, TransformerUtils.invokerTransformer("getName"));
Use apache commons collection api.
Upvotes: 6
Reputation: 2311
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);
}
}
Upvotes: 2
Reputation: 9680
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.
Upvotes: 3
Reputation: 2832
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.
Upvotes: 1
Reputation: 11913
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.
Upvotes: 0
Reputation: 47280
You will have to loop through and access each objects getName()
.
Maybe guava can do something fancy ...
Upvotes: 0