基于其他列表属性集合</x>从List <x>中提取对象

时间:2011-04-21 15:43:46

标签: java collections guava

我有一个班级 -

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

我想从List<Data>中提取data1 dataIds {{1}}来提取{{1}}

我的方法应该怎样?如果在性能/效率方面具有可比性,我可以选择guava的功能方法。

3 个答案:

答案 0 :(得分:3)

怎么样

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

P.S。 remember not to overcomplicate件事,除非真的有必要。

答案 1 :(得分:3)

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

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

我看到你的Data类实现了Identifiable接口。鉴于此,您可以创建一个Function<Identifiable, Integer>来获取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 :(得分:0)

使用LambdaJ,您可以写:

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