Quand il y a un List<Person>
, Y a-t-il une possibilité d'extraire la Liste de tous les person.getName()
de cela? Y a-t-il un appel préparé pour cela, ou dois-je écrire une boucle foreach comme:
List<Person> personList = new ArrayList<Person>();
List<String> namesList = new ArrayList<String>();
for(Person person : personList){
namesList.add(personList.getName());
}
Java 8 et supérieur:
List<String> namesList = personList.stream()
.map(Person::getName)
.collect(Collectors.toList());
Si vous devez vous assurer d'obtenir un ArrayList
en conséquence, vous devez remplacer la dernière ligne par:
...
.collect(Collectors.toCollection(ArrayList::new));
Java 7 et versions antérieures:
L'API de collecte standard antérieure à Java 8 ne prend pas en charge une telle transformation. Vous devrez écrire une boucle (ou l'envelopper dans une fonction "map" de votre choix), à moins que vous ne vous tourniez vers une API/extension de collection plus sophistiquée.
(Les lignes de votre extrait de code Java sont exactement les lignes que j'utiliserais.)
Dans Apache Commons, vous pouvez utiliser CollectionUtils.collect
et un Transformer
En Guava, vous pouvez utiliser la méthode Lists.transform
.
Vous auriez pu le faire mais pour d'autres
en utilisant Java 1.8
List<String> namesList = personList.stream().map(p -> p.getName()).collect(Collectors.toList());
Essaye ça
Collection<String> names = CollectionUtils.collect(personList, TransformerUtils.invokerTransformer("getName"));
Utilisez l'api de la collection Apache commons.
Je pense que vous devrez toujours le faire. Mais si vous aurez toujours besoin de telles choses, je suggérerais de créer une autre classe, par exemple appelez-la People
où personList
est une variable.
Quelque chose comme ça:
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
}
}
Dans ce cas, vous n'aurez besoin d'appeler qu'un seul getter à chaque fois.
Non testé mais c'est l'idée:
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);
}
}
jetez un oeil à http://code.google.com/p/lambdaj/ - il existe un équivalent LINQ pour Java. Son utilisation n'évitera pas d'itérer sur tous les éléments, mais le code serait plus compressé.
Vous devrez parcourir et accéder à chaque objet getName()
.
Peut-être que goyave peut faire quelque chose d'extraordinaire ...
Il n'y a pas d'autre moyen de le faire dans Java que celui que vous avez suggéré, au moins tant que vous respectez la norme Java API de collecte).
Je souhaitais quelque chose comme ça depuis longtemps ... Surtout depuis que j'ai goûté à la douce liberté de Ruby, qui a des choses merveilleuses comme collecter et sélectionner travailler avec des fermetures.