Получить список атрибутов объекта в списке
Когда есть 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());
}
Ответы
Ответ 1
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/расширению коллекции fancier.
(Строки в вашем фрагменте Java - это именно те строки, которые я использовал бы.)
В Apache Commons вы можете использовать CollectionUtils.collect
и Transformer
В Guava вы можете использовать метод Lists.transform
.
Ответ 2
Попробуйте это
Collection<String> names = CollectionUtils.collect(personList, TransformerUtils.invokerTransformer("getName"));
Используйте коллекцию apache commons api.
Ответ 3
Возможно, вы сделали это, но для других
с использованием Java 1.8
List<String> namesList = personList.stream().map(p -> p.getName()).collect(Collectors.toList());
Ответ 4
Я думаю, вам всегда нужно это делать. Но если вам всегда понадобятся такие вещи, я бы предложил сделать другой класс, например, называть его 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
}
}
В этом случае вам нужно будет вызывать один приемник только каждый раз.
Ответ 5
Не тестировалось, но это идея:
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);
}
}
Ответ 6
взгляните на http://code.google.com/p/lambdaj/ - эквивалент LINQ для Java. Использование этого не позволит избежать повторения всех элементов, но код будет более сжатым.
Ответ 7
Вам придется прокручивать и обращаться к каждому объекту getName()
.
Возможно, guava может сделать что-то фантастическое...
Ответ 8
Нет другого способа сделать это в Java, чем тот, который вы предложили, по крайней мере, пока вы придерживаетесь стандартного API Java Collection.
Я давно желаю чего-то подобного... Тем более, что я попробовал сладкую свободу Ruby, у которой есть замечательные вещи, такие как сбор и выбор работы с закрытием.