收集集合中对象的属性

时间:2011-11-21 10:31:39

标签: java collections properties

在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 个答案:

答案 0 :(得分:2)

使用Guava,特别是function interface

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

并像这样调用(其中transform是来自guava的Collections2的静态导入:

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

番石榴也有很多other benefits

答案 1 :(得分:1)

使用Apache Commons'BeanUtils和集合:

Collection<Long> ids = CollectionUtils.collect(things,
        new BeanToPropertyValueTransformer("id"));

答案 2 :(得分:0)

Groovy中你只需要这样做:

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

这样可以将Ids中所有内容Things作为列表提供给您。

以下是一些info on Groovy和一些differences compared to Java

答案 3 :(得分:0)

您可以尝试此方法。它需要一个集合,一个方法(来自反射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();
}

答案 4 :(得分:0)

不是真正的答案,但你可以等待java 8,它将支持lambda表达式。除此之外,我认为番石榴是你最好的选择。