【问题标题】:intersection of two list of different object in javajava中两个不同对象列表的交集
【发布时间】:2012-02-12 01:15:34
【问题描述】:

我有两个 Pojo 类,具有不同的字段和唯一的 ID。

我想执行两个 List<A>List<B> 的交集。

什么是最好的方法。一个是我可以简单地迭代两次,但是复杂度太高了 n2。

有更好的方法吗?我可以用 Comparator 做吗?

Class A {
Id, Name ,DOB}

Class B{
id, aid ,location }

我有 A 列表和 B 列表

现在想要获取位置在 B 中的 A 列表

【问题讨论】:

  • 您的列表是否已排序(在 id/Id 上)?
  • @Bohemian、SetList 并不完全相同。
  • 不,我从来没有说过我想和 Set 一起做。 No List 未排序。
  • @Paul 为此目的:只需使用 new HashSet<?>(list) x 2 即可。

标签: java algorithm


【解决方案1】:

使用 Java 8 流

List<A> listA = new ArrayList<A>();
List<B> listB = new ArrayList<B>();

Set<Integer> aIdsFromBList = listB.stream().map(B::getAId).collect(Collectors.toSet());

return listA.stream
    .filter(a -> aIdsFromBList.contains(a.getId()))
    .collect(Collectors.toList());

【讨论】:

    【解决方案2】:

    试试这个:

    public static void main(String[] args) {System.nanoTime()
        List<A> as = new ArrayList<A>();
        List<B> bs = new ArrayList<B>();
    
        // Collect all A.ids in the list of B into a Set
        Set<String> baids = new HashSet<String>();
        for (B b : bs)
            baids.add(b.aid);
    
        // iterate through the list of A discarding those that don't have a B
        for (Iterator<A> i = as.iterator(); i.hasNext();)
            if (!baids.contains(i.next().Id)) // contains() executes fast for a Set
                i.remove();
    
        // now list "as" contains all A that have a B with A.Id = B.aid 
    }
    

    【讨论】:

    • 所需的输出是一个“位置在B中的A列表”。这个算法是如何实现的?
    • 但是我做第一个for循环从一个列表中获取ID,第二个for循环从第二个列表中获取并在内部保留所有也在做for循环,之后我将再运行一个for循环得到准确的对象。我们可以使用对象并覆盖等于吗?
    • @aix(我觉得天啊...我必须用勺子喂食吗?)很好...我又添加了一行来说明如何解决从集合中获取列表的奥秘。
    • 目前还不完全清楚谁需要给谁喂食,但您的main() 的最后一行可能甚至无法编译。即使是这样,您也失去了A 的所有属性。坦率地说,我认为这场辩论对我们双方来说都是浪费时间。我们显然不在同一个页面上。
    • @aix 是的,我没有考虑过代码。我已将其修复为我认为很好的解决方案。
    【解决方案3】:

    您可以将List&lt;B&gt; 的元素放入HashMap&lt;Integer,B&gt;,其中id 是键。

    完成后,您可以遍历 List&lt;A&gt; 的元素并使用哈希映射快速查找对应的 B 元素。这将提供您需要的结构(“A 列表,位置在B”)。

    【讨论】:

    • -1 你一定是在开玩笑。 真的 废话解决方案,但如果您必须这样做,请使用Set,而不是Map(无论如何,您只使用地图的键集 - 这看起来很熟悉.. keySET ?... SET?) 天啊...
    • @Bohemian:您显然有不同的解决方案。您为什么不继续发布它作为答案?
    • 公平挑战 - 我已经发布了一个解决方案。这是漫长的一天的结束 - 对不起'tude。我本可以说得更好。但是Map 是错误的工具仍然是正确的
    【解决方案4】:
    1. 按 ID 升序对两个列表进行排序。

    2. 从List A开始,在List B中找到对应的索引。 记住列表 B 的当前索引。说 (indB)

    3. 从List A的下一个索引开始,在List B中从(indB+1)开始比较

    4. 从第 1 步重复到第 4 步,直到列表 A 结束或列表 B 结束。

    【讨论】:

      【解决方案5】:

      Apache Commons Collections 有一个方法可以做到这一点:CollectionUtils.intersection。但是,它不使用泛型。

      还有这个SO问题:List intersection in java

      【讨论】:

      • 请务必注意,CollectionUtils.intersection 不保证结果中项目的顺序(它的返回类型是 Collection)。由于您正在处理列表,请记住这一点。
      • 如果顺序很重要,你应该试试 ListUtils.intersection。
      猜你喜欢
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-31
      • 2022-01-21
      • 2015-10-19
      • 1970-01-01
      相关资源
      最近更新 更多