比较Java中的集合;操作在两个方向上都不能按预期工作

时间:2015-07-05 16:46:15

标签: java set removeall

创建了两组不同的大小,但有一些共同的元素,目的是识别每组中的元素,使其与另一组不同。 Java中的Set类似乎有一个很好的方法:removeAll。我做了以下事情:

import java.util.*;

public class HelloWorld {

    @SuppressWarnings("unchecked")
    public static void main(String args[]) {

        // Create a new set
        Set<String> mySet1 = new HashSet();

        // Add elements
        mySet1.add("1");
        mySet1.add("2");
        mySet1.add("4");
        mySet1.add("5");
        mySet1.add("6");
        mySet1.add("7");

        // Print the elements of the Set1
        System.out.println("mySet1: " + mySet1);

        // Create a new set
        Set<String> mySet2 = new HashSet();

        // Add elements
        mySet2.add("1");
        mySet2.add("2");
        mySet2.add("3");
        mySet2.add("5");
        mySet2.add("6");
        mySet2.add("7");
        mySet2.add("8");

        System.out.println("mySet2: " + mySet2);

        // Compare the two sets
        System.out.println("MySet1 matches mySet2: " + mySet1.equals(mySet2));

        // Remove all elements of mySet2 from mySet1
        Set<String> deletions = mySet1;
        deletions.removeAll(mySet2);
        System.out.println("deletions: " + deletions);

        // Remove all elements of mySet1 from mySet2
        Set<String> updates = mySet2;
        updates.removeAll(mySet1);
        System.out.println("updates: " + updates);
    }
}

结果是:

mySet1: [1, 2, 4, 5, 6, 7]
mySet2: [1, 2, 3, 5, 6, 7, 8]
MySet1 matches mySet2: false
deletions: [4]
updates: [1, 2, 3, 5, 6, 7, 8]

为什么“更新”的结果不是&#39; [3,8]

5 个答案:

答案 0 :(得分:3)

由于deletions分配,

mySet1引用与Set<String> deletions = mySet1相同的设置。因此,deletions.removeAll已从原始集mySet1中删除了元素,因此第二个removeAll收到了一个仅包含&#34; 4&#34;的集合。

您应该创建原始集的副本,以免改变mySet1mySet2

Set<String> deletions = new HashSet<>(mySet1); // create a copy of mySet1
deletions.removeAll(mySet2);
System.out.println("deletions: " + deletions);

// Remove all elements of mySet1 from mySet2
Set<String> updates = new HashSet<>(mySet2); // create a copy of mySet2
updates.removeAll(mySet1);
System.out.println("updates: " + updates);

答案 1 :(得分:2)

Set<String> deletions = mySet1;
deletions.removeAll(mySet2);

您刚刚从mySet2删除了所有mySet1。将另一个变量分配给对象不会复制该对象。您可以使用HashSet的构造函数轻松复制它:

Set<String> deletions = new HashSet<String>(mySet1);
deletions.removeAll(mySet2);

答案 2 :(得分:2)

您在此处执行的操作称为symmetric difference。您正在寻找A - B和B - A中的元素的并集(带有集合减法)。

您的代码会覆盖您的原始集合,因此创建新// Remove all elements of mySet2 from mySet1 Set<String> deletions = new HashSet<>(mySet1); deletions.removeAll(mySet2); System.out.println("deletions: " + deletions); // Remove all elements of mySet1 from mySet2 Set<String> updates = new HashSet<>(mySet2); updates.removeAll(mySet1); System.out.println("updates: " + updates); s应该是一件简单的事情,以确保操作不会改变任何内容。

// prints the numbers 4, 3, and 8 in no guaranteed order
System.out.println(Sets.symmetricDifference(mySet1, mySet2));

或者,Google Guava提供Sets utility,其symmetricDifference方法:

data.frame

答案 3 :(得分:1)

在下一行中,您已指定删除引用mySet1对象,因此现在删除和mySet1都指向同一对象。     设置删除= mySet1; 之后你删除了mySet2中包含的所有删除元素,只留下一个元素4的删除。因为,mySet1和删除都指向同一个对象,所以这意味着mySet1还剩下一个元素,即4。 当您尝试从mySet2中删除mySet1的所有元素时,它只是尝试从mySet2中删除元素4。因此输出。

答案 4 :(得分:0)

使用以下代码:

Set<String> deletions = mySet1;

您已经创建了另一个对同一组的引用。两个删除和mySet1 现在有2个变量指向同一个集合。使用以下行,您已经更改了此集合的内容。

deletions.removeAll(mySet2);

实际上,现在mySet1也只包含删除所包含的元素,因为它们都只是指向同一个集合的引用。这就是为什么用以下代码得到了意想不到的结果

updates.removeAll(mySet1);

您需要创建单独的集合副本,以便获得预期的结果。您可以通过以下方式执行此操作:

Set<String> deletions = new HashSet<>(mySet1);