Получить список атрибутов объекта в списке - PullRequest
35 голосов
/ 05 сентября 2011

Когда есть List<Person>, есть ли возможность получить список всех person.getName() из этого?Есть ли готовый вызов для этого, или я должен написать цикл foreach, например:

List<Person> personList = new ArrayList<Person>();
List<String> namesList = new ArrayList<String>();
for(Person person : personList){
    namesList.add(personList.getName());
}

Ответы [ 8 ]

72 голосов
/ 05 сентября 2011

Java 8 и выше:

List<String> namesList = personList.stream()
                                   .map(Person::getName)
                                   .collect(Collectors.toList());

Если вам необходимо убедиться, что в результате вы получите ArrayList, вам нужно изменить последнюю строку на:

                                    ...
                                    .collect(Collectors.toCollection(ArrayList::new));

Java 7 и ниже:

Стандартный API-интерфейс сбора данных до Java 8 не поддерживает такое преобразование.Вам придется написать цикл (или обернуть его в какую-нибудь собственную функцию «map»), если только вы не обратитесь к более интересному API / расширению коллекции.

(Строки в вашем фрагменте Java в точности соответствуютя бы использовал строки.)

В Apache Commons вы могли бы использовать CollectionUtils.collect и Transformer

В Гуаве вы могли быиспользуйте метод Lists.transform.

9 голосов
/ 04 ноября 2014

Вы могли бы сделать это, но для других

, используя Java 1.8

List<String> namesList = personList.stream().map(p -> p.getName()).collect(Collectors.toList()); 
6 голосов
/ 22 ноября 2013

Попробуйте это

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

Используйте Apache Commons Collection Api.

2 голосов
/ 05 сентября 2011

Не проверено, но это идея:

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 голосов
/ 05 сентября 2011

Я думаю, вам всегда нужно будет это делать. Но если вам всегда будут нужны такие вещи, то я бы предложил создать другой класс, например, назвать его People, где personList - это переменная.

Примерно так:

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
    }
}

В этом случае вам нужно будет каждый раз вызывать только одного геттера.

1 голос
/ 05 сентября 2011

взгляните на http://code.google.com/p/lambdaj/ - есть эквивалент LINQ для Java.Его использование не исключает повторения всех элементов, но код будет более сжатым.

0 голосов
/ 05 сентября 2011

Нет другого способа сделать это в Java, кроме того, который вы предложили, по крайней мере, пока вы придерживаетесь стандартного API Java Collection.

Я хотел чего-то подобного длядолгое время ... Тем более, что я попробовал сладкую свободу Ruby, в которой есть такие замечательные вещи, как собирать и выбирать, работая с замыканиями.

0 голосов
/ 05 сентября 2011

Вам придется проходить и получать доступ к каждому объекту getName().

Может быть гуава может сделать что-то необычное ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...