为什么不使用 Arrays.asList 创建的列表对值进行拆箱?
Why don't lists created with Arrays.asList unbox the values?
我一直在用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 不会复制值,而是 "backed" 原始数组。但是,比较函数中的 get(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
但是因为您的代码保持在缓存整数的范围内,所以它应该可以正常工作。
如果您使用 ==
与 Object
进行比较,则您只比较参考文献。在这种情况下不需要使用自动拆箱。此外 Java 有时可以通过只创建一次来节省堆来优化创建相同的对象,因此通过引用进行比较有时有效,有时无效。
我一直在用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 不会复制值,而是 "backed" 原始数组。但是,比较函数中的 get(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
但是因为您的代码保持在缓存整数的范围内,所以它应该可以正常工作。
如果您使用 ==
与 Object
进行比较,则您只比较参考文献。在这种情况下不需要使用自动拆箱。此外 Java 有时可以通过只创建一次来节省堆来优化创建相同的对象,因此通过引用进行比较有时有效,有时无效。