2011-01-26 2 views
7

Предположим, что у меня есть объект, который выглядит как:Как получить список атрибутов из ArrayList объектов

public class Obj { 
String foo; 
String bar; 
} 

Если я создаю ArrayList типа Obj и заполнить его, есть способ, которым я могу вернуть список все объекты в атрибуте foo массива из ArrayList?

EDIT: Я должен был быть более ясным, я не хочу, чтобы сделать это с помощью итерации

+0

У вас есть список OBJS и хотите создать второй список из этого списка , который содержит атрибут Foo всех Obj из objs? – Ralph

ответ

7

Вам придется повторять через List<Obj> и сверить записи Foo в новый List

например

List<String> foos = new ArrayList<String>(); 
for (Obj obj : objs) { 
    foos.add(obj.foo) 
} 

или Java 8 и выше, использование потоков таким образом:

objs.stream().map(o -> o.foo).collect(toList()); 
+3

моей первой версией было goign для этого: 'var foos = objs.Select (x => x.foo);' до тех пор, пока я не понял, что это вопрос Java. Черт бы тебя побрал! –

+0

Вы можете сделать эквивалент 'map' в простой Java, используя что-то вроде Guava. Существует (немного) больше работы, очевидно, но она имеет преимущества перед распределением памяти для копии всех значений 'foo' в исходном списке. – ColinD

+1

Является ли Java 8 Lambda какой-либо новой уловкой для этого? Ала - обман scala-LINQ. – ken

0

итерации через список и создать набор всех свойств Foo.

0

что-то вроде этого?

List<String> foos = new ArrayList<String>(); 
for (Obj obj : objList) 
{ 
    foos.addElement(obj.foo); 
} 
4

Использование Guava вы можете создать вид foo собственности объектов в List используя Lists.transform так:

public class Obj { 
    String foo; 
    String bar; 

    public static final Function<Obj, String> FOO = new Function<Obj, String>() { 
    public String apply(Obj input) { 
     return input.foo; 
    } 
    }; 
} 

public void someMethod(List<Obj> objs) { 
    List<String> foos = Lists.transform(objs, Obj.FOO); 
    ... 
} 

В отличие от других решений, это чисто вид из List<Obj> и как таковой он не выделяет целого отдельного ArrayList или некоторых таких в памяти и может быть создан практически без какого-либо времени независимо от размера вашего List<Obj>. Кроме того, если вы измените оригинал List<Obj>, список foos отразит это изменение.

В Java 8 (ожидается в 2012 году), это станет намного проще с помощью лямбда-выражений и ссылок на методы. Вы будете в состоянии сделать что-то вроде этого:

List<Obj> objs = ... 
List<String> foos = objs.map(#Obj.getFoo); 
10

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

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

Использование Apache Commons коллекция апи.

+0

Спасибо, этот метод прост и быстр – Vito

1

Ответ @Surodip использует компактное решение на основе Apache Commons Collections. Но это решение не типизированного, так как трансформаторные ссылается свойство с помощью строкового выражения: TransformerUtils.invokerTransformer("getName")

Вот более многословным, но типизированного решение с использованием Apache Commons Коллекции:

Collection<String> values = CollectionUtils.collect(messages, new Transformer<Obj, String>(){ 

      @Override 
      public String transform(Obj input) { 
       return input.getFoo(); 
      } 

     }); 

Вышеуказанные решения использует Apache Commons Collection Version> = 4, который поддерживает дженерики для безопасности типов.

Ниже менее типизированная версия для Apache Collections версии < 4, которая не использует дженерик:

Collection values = CollectionUtils.collect(messages, new Transformer(){ 

      @Override 
      public Object transform(Object input) { 
       Obj obj = (Obj) input; 
       return obj.getFoo(); 
      } 

     }); 
Смежные вопросы