为什么不使用Arrays.asList创建的列表取消设置值?

时间:2017-09-14 14:33:21

标签: java arraylist wrapper comparator

我一直在使用Arrays.asList制作二维ArrayList,如下所示:

ArrayList<List<Integer>> li = new ArrayList<List<Integer>>();
for(int i = 0; i < 100; i++){
    li.add(Arrays.asList(1, (int)(Math.random() * 100)));
}

当我尝试按如下方式对元素进行排序时:

Collections.sort(li, new Comparator<List<Integer>>(){
    public int compare(List<Integer> l1, List<Integer> l2){
        if(l1.get(0) == l2.get(0)){
            return l1.get(1) - l2.get(1);
        }
        return l1.get(0) - l2.get(0);
    }
});

第二个索引没有正确排序元素。

但是,当我不使用Arrays.asList时,请创建新的ArrayList:

ArrayList<List<Integer>> li = new ArrayList<List<Integer>>();
for(int i = 0; i < 100; i++){
    ArrayList<Integer> toAdd = new ArrayList<Integer>();
    toAdd.add(1); 
    toAdd.add((int)(Math.random() * 100));
    li.add(toAdd);
}

然后排序工作。

据我所知,Arrays.asList并不会复制这些值,而是&#34;支持&#34;由原始数组。但是,不应该在比较功能内部get(0)调用自动取消装箱值?

2 个答案:

答案 0 :(得分:0)

我能发现的唯一问题是以下if语句:

if(l1.get(0) == l2.get(0)) {
}

它比较所有列表的第一个索引,在给定代码中始终为1。当您使用==运算符时,实际上是在比较对象引用。不是它们的值相等,而是两个不同的变量是否指向内存中完全相同的对象。

只要比较-128到127之间的整数,这是可以的。此范围内的值是缓存,因此类型Integer的两个不同变量可以引用同一个对象。

Integer a = 127;
Integer b = 127;
System.out.println(a == b); // prints true

Integer c = 128;
Integer d = 128;
System.out.println(c == d); // prints false

但是因为你的代码保持在缓存整数的范围内,所以它应该可以正常工作。

答案 1 :(得分:0)

如果您使用==Object进行比较,则仅比较参考。在这种情况下,无需使用自动装箱。此外,Java有时可以通过仅创建一次来保存堆来优化创建相同的对象,因此通过引用进行比较有时会起作用,有时候也不会。