写在前面:今天刷LeetCode的时候发现一个测试用例始终过不去,代码出问题处大概表述如下:
List<Integer> a = new ArrayList<>();
a.add(300);
List<Integer> b = new ArrayList<>();
b.add(300);
if(a.get(0) == b.get(0)){
代码块B
}
else{
代码块C
}
题主的目的是为了让代码进入代码块B,但是最后代码都进入了C,所以题主查资料做测试,诞生了下面这个文章。
1.Integer和int:
题主在开头的时候就写了List< Integer >,所以我们的列表里只能放入Integer对象,但是其实我们放进去的不一定是一个新的Integer对象。即我们每次add的操作不一定是add(new Integer(数值))。
首先我们先确认,Integer和int的区别有哪些:
1Integer是int的包装类;int是基本数据类型;
2.Integer变量必须实例化后才能使用;int变量不需要;
3.Integer实际是对象的引用,指向此new的Integer对象;int是直接存储数据值 ;
4.Integer的默认值是null;int的默认值是0
2.什么时候是相等的
我们首先要知道一点,java里自带一个Integer类型的常量池,即-128~127(即8位2进制位能表示的补码的值),当我们使用int进行Integer对象的初始化时,若int值在-128到127之间,则不会为其开辟一个新的空间,而是直接指向常量池,而当在这个范围之外时,会默认执行new Integer(int的值),会开辟一个新的空间。代码证明如下
List<Integer> ame = new ArrayList<>();
List<Integer> bme =new ArrayList<>();
for(int i = -130;i < 130;++i){
ame.add(i);
bme.add(i);
}
for(int i= 0; i < ame.size(); ++i){
if(ame.get(i) == bme.get(i));
else System.out.println(ame.get(i));
}
输出结果为:
我们可以看到,-128到127返回的都是想等的,即表示了他们所指的是同一片空间,当在这个范围之外时,则需要进行new一个新空间,这个时候==比较两者的空间所在地,空间不同返回则为false;
3.更有效的解决方式
使用Integer.equals()
for(int i= 0; i < ame.size(); ++i){
if(ame.get(i).equals(bme.get(i)));
else System.out.println(ame.get(i));
}
输出结果:
直接调用equals方式进行值的比较而不是进行地址的比较
后记:Integer.equals()的注意事项
调用equals函数的前提是该Integer对象的值不为null,即null可以作为equals的参数,但是不能作为调用equals的对象的值:
即这样子会报错
public static void main(String[] args) {
List<Integer> ame = new ArrayList<>();
List<Integer> bme =new ArrayList<>();
ame.add(null);
bme.add(1);
if(ame.get(0).equals(bme.get(0)))
System.out.println(1);
}
这样子则不会报错
public static void main(String[] args) {
List<Integer> ame = new ArrayList<>();
List<Integer> bme =new ArrayList<>();
ame.add(1);
bme.add(null);
if(ame.get(0).equals(bme.get(0)))
System.out.println(12138);
}
这个地方十分容易出现问题,所以在做题时最好先进行是否为null的判断