“add()”函数在清除列表后显示异常行为,然后再次添加到同一列表中

"add()" function showing unusual behavior after clearing list and then adding again to the same list

提问人:Vishal Sangole 提问时间:8/14/2023 最后编辑:MarkusAndVishal Sangole 更新时间:8/15/2023 访问量:54

问:

给定两个 0 索引整数数组 和 ,返回一个大小为 2 的列表答案,其中:nums1nums2

  • answer[0]是 中不存在的所有不同整数的列表。nums1nums2
  • answer[1]是 中不存在的所有不同整数的列表。nums2nums1

请注意,列表中的整数可以按任意顺序返回。

我特意在那里留下了打印语句以进行调试。

class Solution {
    public List<List<Integer>> findDifference(int[] nums1, int[] nums2) {
        Set<Integer> set1 = new HashSet<>();
        Set<Integer> set2 = new HashSet<>();
        List<List<Integer>> ans = new ArrayList<>();
        for(int i : nums2){
            set2.add(i);
        }
        List<Integer> list = new ArrayList<>();
        for(int i : nums1){
            set1.add(i);
            if(!set2.contains(i)) list.add(i);
        }
        System.out.println(list);
        ans.add(list);
        System.out.println(ans);
        list.clear();
        System.out.println(list);
        for(int i : nums2){
            if(set1.add(i)) {
                list.add(i);
            }
        }
        System.out.println(list);
        ans.add(list);
        System.out.println(ans);

        return ans;
    }
}

输入:

nums1 = [1,2,3]
nums2 = [2,4,6]

输出:

[1, 3]
[[1, 3]]
[]
[4, 6]
[[4, 6], [4, 6]]

的最终值应该是 而不是 。 有人知道为什么会这样吗?ans[[1,3],[4,6]][[4, 6], [4, 6]]

java list 调试 arraylist

评论

1赞 Jon Skeet 8/14/2023
是的 - 您已经添加了两次。这是对同一对象的两次引用。而不是我怀疑你想要创建一个列表,而不是只清除现有的列表(它仍然在 中引用)。listanslist.clear()list = new ArrayList<>();ans
0赞 8/14/2023
将相同的 List 添加到您的对象两次,而不是添加 2 个不同的 List 对象。执行操作不会创建 的副本。因此,您对该列表所做的任何修改都将在引用该列表的所有位置可见。List<List<Integer>> ansand.add(list)List<Integer> list
0赞 8/14/2023
这回答了你的问题吗?为什么我的 ArrayList 包含添加到列表中的最后一项的 N 个副本?

答:

2赞 Loginus 8/14/2023 #1
ans.add(list);

在这里,你添加了对对象的引用,但它是一个引用而不是一个副本,所以无论你在其中更改什么,它也会反映在 中。如果在 ,listlistansSystem.out.println(ans)System.out.println(list)

ans.add(list);
System.out.println(ans);
list.clear();
System.out.println(list);
System.out.println(ans);

你会知道的。因此,引用的内容是空的。然后在脚本的末尾,你只需再添加一次引用,所以很简单 - 无论你在 中有什么,你都有两次 。 解决方案是添加对象的副本而不是引用 - 使用:[[]]listlistans

ans.add(new ArrayList<>(list));

而不是:

ans.add(list);

两次在代码中

如果你可以使用标准 Java,你可以简化你的代码,比如:

public List<List<Integer>> findDifference(Integer[] nums1, Integer[] nums2) {
    Set<Integer> set1 = Set.of(nums1);
    Set<Integer> set2 = Set.of(nums2);
    Set<Integer> set1_not2 = new HashSet<>(set1);
    set1_not2.removeAll(set2);

    Set<Integer> set2_not1 = new HashSet<>(set2);
    set2_not1.removeAll(set1);

    return List.of(new ArrayList<>(set1_not2), new ArrayList<>(set2_not1));
}