从 List中提取对象基于一些其他列表属性集合

发布于 2024-11-02 14:14:25 字数 467 浏览 1 评论 0原文

我有一个类 -

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 ,它的 id 在 dataIds 中>

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

I've a class -

public class Data implements Identifiable{
    private Integer id;

    public Integer getId(){
        return id;
    }
}

now I've two collections-

List<Data> data1 = // few hundred Objects

Set<Integer> dataIds = // few object ids

I would like to extract the List<Data> from data1 which has ids in dataIds

How should be my approach? I'va guava in my classpath so can go with guava's Functional approach if comparable in performance/efficiency .

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

凝望流年 2024-11-09 14:14:25

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

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

我看到您的 Data 类实现了 Identifying 接口。鉴于此,您可以创建一个 Function 来获取 ID...Identifyings.getIdFunction() 或其他内容。这很好,因为它可能在其他各个地方都很有用(我在博客文章 此处)。有了这个,使用 Guava 执行此操作也将相当简单:

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

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

Unless all you want to do is iterate through the result once or you need a reusable live filtered view, you probably want a non-view list containing the matches. Creating a List or Set to store the result and then iterating through the data list and adding matches is a perfectly good approach and easy to understand!

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

I see your Data class implements an Identifiable interface. Given that, you could create a Function<Identifiable, Integer> that gets the ID... Identifiables.getIdFunction() or something. This is nice because it'd likely be useful in various other places (I talk about that approach in a blog post here). With that in place, doing this with Guava would be fairly simple as well:

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

This is basically functionally equivalent to the first example, but seems like it'd be harder to understand. Since there isn't any clear benefit to doing this (unlike in a situation where you want to just use the live view), my recommendation would be to just go with the first.

白日梦 2024-11-09 14:14:25

怎么样

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

记住不要让事情变得过于复杂,除非确实有必要。

How about

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

p.s. remember not to overcomplicate things, unless truly necessary.

逐鹿 2024-11-09 14:14:25

使用 LambdaJ 您可以编写:

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

With LambdaJ you could write:

List<Data> result = extract(data1, on(Data.class).getId());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文