web-dev-qa-db-fra.com

Obtenir la liste des attributs d'un objet dans une liste

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());
}
38
Sonnenhut

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 .

79
aioobe

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()); 
10
fjkjava

Essaye ça

Collection<String> names = CollectionUtils.collect(personList, TransformerUtils.invokerTransformer("getName"));  

Utilisez l'api de la collection Apache commons.

6
Surodip

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 PeoplepersonList 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.

2
medopal

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);
    }
}
2
Simone

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é.

1

Vous devrez parcourir et accéder à chaque objet getName().

Peut-être que goyave peut faire quelque chose d'extraordinaire ...

0
NimChimpsky

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.

0
fgysin