有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

用Java比较集合;操作在两个方向上均未按预期工作

创建了两个不同大小的集合,但有一些共同的元素,目的是识别每个集合中使其不同于另一个集合的元素。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]

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


共 (3) 个答案

  1. # 1 楼答案

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

  2. # 2 楼答案

    使用以下代码:

    Set<String> deletions = mySet1;
    

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

    deletions.removeAll(mySet2);
    

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

    updates.removeAll(mySet1);
    

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

    Set<String> deletions = new HashSet<>(mySet1);
    
  3. # 3 楼答案

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

    您刚刚从mySet1中删除了所有mySet2。将另一个变量指定给对象不会复制该对象。使用HashSet的构造函数,您可以很容易地复制它:

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