联合和java集的交集

Mah*_*zad 3 java collections set set-intersection set-union

Set在java中建立联合或s 交集的最简单方法是什么?我已经看到了这个简单问题的一些奇怪的解决方案(例如手动迭代这两个集合).

在此输入图像描述 在此输入图像描述

Mah*_*zad 11

最简单的单行解决方案是:

set1.addAll(set2); // Union
Run Code Online (Sandbox Code Playgroud)
set1.retainAll(set2); // Intersection
Run Code Online (Sandbox Code Playgroud)

以上解决方案具有破坏性,意味着原始set1的内容发生了变化.如果您不想触摸现有的集,请创建一个新集:

Set<E> result = new HashSet<>(set1);
 // ?? your specific type
Run Code Online (Sandbox Code Playgroud)
result.addAll(set2); // Union
Run Code Online (Sandbox Code Playgroud)
result.retainAll(set2); // Intersection
Run Code Online (Sandbox Code Playgroud)

  • @ArnaultLePrévost-Corvellec参考?使用`clone()`是非常不受欢迎的,建议在所有情况下都要避免使用.参见[Effective Java 11](https://medium.com/@biratkirat/learning-effective-java-item-11-390fbf94e41c)(原书,[完整PDF](http://wavelino.coffeecup.com/pdf /EffectiveJava.pdf))(第3版第13项) (3认同)
  • 您说的是可克隆的接口,实现起来可能非常棘手,而且大多数情况下,开发人员不尊重克隆的合同。我不会证明 HashSet.clone() 方法尊重克隆契约......如果你看到不同之处,请阅读这些方法的代码。这里的目的是制作一个浅拷贝,克隆制作得最快作为构造函数是任何集合的代码...... hashset add 方法非常繁重,这就是为什么对于性能问题,克隆将是最好的方法...... (2认同)

Nit*_*sht 7

您可以使用Google's Guava library. 下面结合示例给出以下解释:

    // Set a
    Set<String> a = new HashSet<String>();
    a.add("x");
    a.add("y");
    a.add("z");

    // Set b
    Set<String> b = new HashSet<String>();
    b.add("x");
    b.add("p");
    b.add("q");
Run Code Online (Sandbox Code Playgroud)

现在,在 Java 中计算两个 Set 的交集:

Set<String> intersection = Sets.intersection(a, b);
System.out.printf("Intersection of two Set %s and %s in Java is %s %n",
                a.toString(), b.toString(), intersection.toString());
Run Code Online (Sandbox Code Playgroud)

输出: Intersection of two Set [z, y, x] and [q, p, x] in Java is [x]

同样,Java 中计算两个 Set 的并集:

Set<String> union = Sets.union(a, b);
System.out.printf("Union of two Set %s and %s in Java is %s %n",
                a.toString(), b.toString(), union.toString());
Run Code Online (Sandbox Code Playgroud)

输出: Union of two Set [z, y, x] and [q, p, x] in Java is [q, p, x, z, y]

您可以在https://google.github.io/guava/releases/18.0/api/docs/阅读有关番石榴库的更多信息

为了将番石榴库添加到您的项目中,您可以看到/sf/answers/325426321/

  • @Zabuza 它提供了一个交集/联合 _view_ - 这与 JDK 选项非常不同。当然,如果您不需要那个,那么库是不必要的。 (3认同)
  • 虽然库方法很好,但我认为没有任何理由在 Java 已经提供时添加重量级库和仅用于 set-intersection/union 的所有开销。当然,如果你的项目中已经有了它,你可以直接使用它。 (2认同)

Dav*_*ren 5

虽然番石榴肯定是更整洁和相当标准的,但这是一种仅使用标准Java进行合并和相交的非破坏性方法

Set s1 = Set.of(1,2,3);
Set s2 = Set.of(3,4,5);     

Set union = Stream.concat(s1.stream(),s2.stream()).toSet(); 
Set intersect = s1.stream().filter(s2::contains).toSet();
Run Code Online (Sandbox Code Playgroud)

  • 值得注意的是,使用这段代码,不需要将“s1”作为一个集合。任何流都可以工作而不会降低性能(因为正在检查的是“s2”,这就是设置发挥作用的地方) (2认同)