【问题标题】:Extracting objects from List<X> based on some other list property collection根据其他一些列表属性集合从 List<X> 中提取对象
【发布时间】:2011-04-21 15:43:45
【问题描述】:

我有课 -

public class Data implements Identifiable{
    private Integer id;

    public Integer getId(){
        return id;
    }
}

现在我有两个系列-

List<Data> data1 = // few hundred Objects

Set<Integer> dataIds = // few object ids

我想从data1 中提取List&lt;Data&gt;,它的ID 在dataIds

我的方法应该如何?我的类路径中有番石榴,因此如果在性能/效率方面具有可比性,可以使用番石榴的功能方法。

【问题讨论】:

  • 如果 dataId 对应于 List 对象的 ID,那么为什么一个是 Integer 而另一个是 Long ?另外,使用什么集合类型?例如: data1 是 ArrayList 还是 LinkedList ?

标签: java collections guava


【解决方案1】:

除非您只想遍历结果一次,或者您需要一个可重复使用的实时过滤视图,否则您可能需要一个包含匹配项的非视图列表。创建ListSet 来存储结果,然后遍历数据列表并添加匹配项是一种非常好的方法并且易于理解!

List<Data> result = Lists.newArrayList();
for (Data data : data1) {
  if (dataIds.contains(data.getId()))
    result.add(data);
}

我看到你的 Data 类实现了一个 Identifiable 接口。鉴于此,您可以创建一个 Function&lt;Identifiable, Integer&gt; 来获取 ID...Identifiables.getIdFunction() 或其他东西。这很好,因为它可能在其他各种地方都很有用(我在博客文章 here 中谈到了这种方法)。有了这些,使用 Guava 执行此操作也将相当简单:

Predicate<Identifiable> predicate = Predicates.compose(
    Predicates.in(dataIds), Identifiables.getIdFunction());
List<Data> filtered = Lists.newArrayList(Iterables.filter(data1, predicate));

这在功能上基本上等同于第一个示例,但似乎更难理解。由于这样做没有任何明显的好处(与您只想使用实时取景的情况不同),我的建议是使用第一个。

【讨论】:

    【解决方案2】:

    怎么样

    Collections2.filter(
        data1,
        new Predicate<Data>() {
           public boolean apply(Data d) {
             return dataIds.contains(d.getId());
           }
        }
    )
    

    附言remember not to overcomplicate 东西,除非真的有必要。

    【讨论】:

      【解决方案3】:

      使用LambdaJ 你可以写:

      List<Data> result = extract(data1, on(Data.class).getId());
      

      【讨论】:

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