Соберите свойство объектов в коллекции - PullRequest
7 голосов
/ 21 ноября 2011

В C # я могу сделать это:

IEnumerable<long> ids = things.select(x => x.Id);

В Java я должен сделать это:

Collection<Long> ids = new ArrayList<Long>(things.size());
for(Thing x : things)
   ids.add(x.getId());

Нужно сделать довольно много сейчас и подуматьесть более общий способ сделать это в Java.Мог бы создать метод для этого, но тогда мне нужно было бы добавить интерфейс с методом getId или что-то в этом роде ... чего я не могу ...

Ответы [ 5 ]

2 голосов
/ 21 ноября 2011

с использованием Guava , в частности, с функциональным интерфейсом :

public class ThingFunction implements Function<Thing, Long> {
    @Override
    public Long apply(Thing thing) {
        return user.getId();
    }
} 

и вызывается следующим образом (где transform - это статический импорт из Collections2 из гуавы:

Collection<Long> ids = transform(things, new ThingFunction());

Гуава имеет немало других преимуществ тоже.

1 голос
/ 28 марта 2014

Использование Apache Commons 'BeanUtils и коллекций:

Collection<Long> ids = CollectionUtils.collect(things,
        new BeanToPropertyValueTransformer("id"));
0 голосов
/ 21 ноября 2011

Вы можете попробовать этот метод. Он берет коллекцию, метод (из api отражения) и целевой класс. Он вызывает метод для всех членов коллекции и возвращает список результатов.

public <T> Collection<T> select(Collection<? extends Object> input, Method getter, Class<T> targetClazz) {
    ArrayList<T> result = new ArrayList<T>();
    for (Object object : input) {
        try {
            Object resultObject = getter.invoke(object, (Object[]) null);
            if (targetClazz.isAssignableFrom(resultObject.getClass())) {
                result.add(targetClazz.cast(resultObject));
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
    return result;
}

Я пока игнорировал правильную обработку ошибок. Использование:

try {

    Method getId = Thing.class.getMethod("getId", null);
    Collection<Long> result = select(things, getId, Long.class);

} catch (SecurityException e) {
    e.printStackTrace();
} catch (NoSuchMethodException e) {
    e.printStackTrace();
}
0 голосов
/ 21 ноября 2011

Не совсем ответ, но вы можете подождать Java 8, который будет поддерживать лямбда-выражения. Кроме этого, я думаю, что Гуава - ваш лучший вариант.

0 голосов
/ 21 ноября 2011

В Groovy вам нужно только сделать это:

Set ids = things.collect{ aThing -> aThing.Id}

Это даст вам все Ids из всех вещей в Things в виде списка.

Вот некоторая информация о Groovy и некоторые различия по сравнению с Java

...