不能直接用两个Integer对象比较大小

现象:

Integer i = new Integer(100);  
Integer j = new Integer(100);  
System.out.println(i==j);  

打印结果是:false

创建了两个Integer型的对象,对象之间的“==”符是用来比较是否是一个对象的两个引用(即比较地址是否相同)

基本类型和包装类型之间可以自由转换,但不能简单地用包装类型代替基本类型比较大小

Integer i = Integer.valueOf(100);  
Integer j = Integer.valueOf(100);  
System.out.println(i==j);  

打印结果是:true
Integer i = Integer.valueOf(400);  
Integer j = Integer.valueOf(400);  
System.out.println(i==j);  

打印结果是:false

查看Integer.valueOf方法的源码,如下: 

public static Integer valueOf(int i) {    
    if(i >= -128 && i <= IntegerCache.high)    
        return IntegerCache.cache[i + 128];    
    else    
        return new Integer(i);    
}    

Integer在比较value大小时,Integer对象有个缓存,如果value值在-128到127之间时,直接返回固定的对象引用,是同一个,肯定是true。但是超过这个范围,就是两个对象了,自然是false

 

解决方案:

即便两个 Integer.valueOf(100)比较得到的结果是True,也是因为两个本身就是同一个对象(地址一样),而不能简单地理解为是两个Integer的value相同

方案一、

一、一个Integer一个int可以直接比较大小

二、两个Integer需要用Integer.intValue()方法比较是否相等:

例如:i.intValue()==j.intValue()

private final int value;

public Integer(int value) {
    this.value = value;
}

// Integer.intValue():
public int intValue() {
    return value;
}

1.intValue()是java.lang.Number类的方法,Number是一个抽象类。Java中所有的数值类都继承它。也就是说,不单是Integer有intValue方法,Double,Long等都有此方法。 
2.此方法的意思是:输出int数据。每个数值类中具体的实现是不同的。例如: 
Float类和Double类的intValue方法,就是丢掉了小数位

方案二、

包装类对象不可使用“==”符做比较运算,如果要进行比较运算时,最好使用java类库中的compareTo方法

// Integer.compareTo()
public int compareTo(Integer anotherInteger) {
    return compare(this.value, anotherInteger.value);
}
public static int compare(int x, int y) {
    return (x < y) ? -1 : ((x == y) ? 0 : 1);
}

方案三、

Integer.equals(Integer)

其实 实现也是用的intValue比较

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

注意:

一般情况下能用int比较 其实是不会选择Integer比较的

但是要注意:

1.

Map.get('c') == Map.get('c')

可能会毫无察觉地判断两个Integer是否相等

2.

把entity字段定义为Integer 也可能 判断Integer是否相等 但自己也没意识到

3.

以上问题只存在于比较Integer是否相等,大于、小于 不会出现该问题

为何?因为==比较的是Integer对象地址,> < 比较的是value(会使用intValue拆箱比较)

4. 

1.int和int之间,用==比较,肯定为true。基本数据类型没有equals方法
2.int和Integer比较,Integer会自动拆箱,== 和 equals都肯定为true
3.int和new Integer比较,Integer会自动拆箱,调用intValue方法, 所以 == 和 equals都肯定为true
4.Integer和Integer比较的时候,由于直接赋值的话会进行自动的装箱。所以当值在[-128,127]中的时候,由于值缓存在IntegerCache中,那么当赋值在这个区间的时候,不会创建新的Integer对象,而是直接从缓存中获取已经创建好的Integer对象。而当大于这个区间的时候,会直接new Integer。
5.当Integer和Integer进行==比较的时候,在[-128,127]区间的时候,为true。不在这个区间,则为false
6.当Integer和Integer进行equals比较的时候,由于Integer的equals方法进行了重写,比较的是内容,所以为true
7.Integer和new Integer : new Integer会创建对象,存储在堆中。而Integer在[-128,127]中,从缓存中取,否则会new Integer.
所以 Integer和new Integer 进行==比较的话,肯定为false ; Integer和new Integer 进行equals比较的话,肯定为true
new Integer和new Integer进行==比较的时候,肯定为false ; 进行equals比较的时候,肯定为true
原因是new的时候,会在堆中创建对象,分配的地址不同,==比较的是内存地址,所以肯定不同


装箱过程是通过调用包装器的valueOf方法实现的
拆箱过程是通过调用包装器的xxxValue方法实现的(xxx表示对应的基本数据类型)
原文链接:https://blog.csdn.net/wxy941011/article/details/80768271

 

更多:https://my.oschina.net/miwang/blog/730343

你可能感兴趣的:(javaSE)