【问题标题】:Collect property of objects in collection收集集合中对象的属性
【发布时间】:2011-11-21 10:31:39
【问题描述】:

在 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 方法的接口或类似的东西......我不能......

【问题讨论】:

  • 我假设things 不继承自集合或数组。
  • 你为什么这么认为?我使用for 循环things,所以至少必须是数组或可迭代的。
  • @Brett Walker 需要一个 id 集合,而不是另一个东西集合
  • @Brett 我不想要另一个事物的集合,我想要事物的某个属性的值的集合,在这个例子中是它们的 id。
  • 你想用这个属性集合做什么。 (旁白:- 没有说明this 的类型。)考虑到更大的上下文,具体问题可能会提供不同的解决方案。

标签: java collections properties


【解决方案1】:

使用Guava,特别是function interface

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());

Guava 也有不少other benefits

【讨论】:

    【解决方案2】:

    使用Apache Commons' BeanUtils 和集合:

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

    【讨论】:

      【解决方案3】:

      Groovy 你只需要这样做:

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

      这将为您提供来自Things 中所有事物的所有Ids 作为列表。

      这里有一些info on Groovy,还有一些differences compared to Java

      【讨论】:

        【解决方案4】:

        不是一个真正的答案,但您可以等待 java 8,它将支持 lambda 表达式。除此之外,我认为 Guava 是您的最佳选择。

        【讨论】:

        • 以Java的速度,这可能需要几十年的时间? :p
        • 它在 2012 年 10 月的计划中,所以它就在拐角处;)
        • 但这不代表到时候我就可以用了,呵呵。在我目前工作的组织中仍然是 1.6...
        • java 8 lambda 表达式 2014 和计数
        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-05-03
          • 1970-01-01
          相关资源
          最近更新 更多