面试必备:对Integer包装类使用==和equals的各种情况。小白也能看懂!!!

==和equals()

双等号是java的比较符,作用如下:

  • 基本类型跟基本类型比较,比较的是数值是否相等
  • 引用类型跟引用类型比较,比较的是引用是否相等(即是否同一个对象)
  • 其他情况:
    //src指向了常量池的字面量“cc”
    String src = "cc";
    //s指向的是String对象,该对象再指向“cc”
    String s = new String("cc")
    System.out.println(src == "cc");//true
    System.out.println(s == "cc");//false
    
    
    int a = 666;
    //其他创建方式也一样
    Integer b = new Integer(666);
    //自动拆箱
    System.out.println(a==b);//true

上述描述大体上是没问题的,但如果你学习过java的内存模型,就会有更深入的认识!

equals()方法,如果使用默认的(继承自Object类),那它用的就是双等号,用来比较引用是否相等!

//obj不仅可以是引用类型,也可以是int类型/数字/字面量,只不过没有意义
public boolean equals(Object obj) {
    return (this == obj);
}

但一般equals()方法都会被重写,比如String重写后的equals()方法,比较的就是字符串的内容是否相等

public boolean equals(Object anObject) {
    //跟本身比较,直接返回true
    if (this == anObject) {
        return true;
    }
    //当且仅当字符串长度相等,且每个字符对应相等,返回true
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

包装类Integer也重写了equals()方法。作用跟上面类似,比较的整数值是否相等

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

无论你通过哪种方式创建的Integer,无论你传进去的是Integer对象还是int类型,只要整数值相等,那equals()方法就返回true。

int a = 133;
Integer b = 133;
Integer c = new Integer(133);

System.out.println(c.equals(a));//true
System.out.println(b.equals(a));//true
System.out.println(c.equals(b));//true

Integer的equals()方法是比较整数值是否相等,不需要考虑各种情况,比较简单。

但使用双等号就不一样了,不是说数值相等就返回true。有各种各样的情况,有些情况是比较整数值,有些情况是比较引用。如果想要了解得更透彻就需要翻一下源码。

Integer创建方式

我们创建Integer对象时,一般都会传进一个value。这里只讨论3种创建方式。

  • 直接new:直接返回Integer对象
  • 直接赋值:返回缓存值或Integer对象
    //返回缓存值
    Integer integer1 = 127;
    //new一个Integer返回
    Integer integer2 = 128;
    
  • 调用静态方法valueOf():返回缓存值或Integer对象
    //入参int,若在缓存值范围则返回缓存值,否则new一个Integer对象返回
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
    
    
    //入参String,调用parseInt()方法将String转为int
    public static Integer valueOf(String s) throws NumberFormatException {
        return Integer.valueOf(parseInt(s, 10));
    }

可以看到,直接赋值和调用静态方法,这种非new的Integer涉及到了缓存值这个概念,那么缓存值指的是什么呢?

这其实跟Integer的底层有关,Integer类里有一个私有静态内部类IntegerCache

private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

这个IntegerCache有什么用呢?简单来说,它开辟了一个数池(具体存储方式是数组),里面存放了-127至128范围的整数。当输入的值(value)在这个数值范围内,返回的是缓存数组中的值;若超过数值范围,则new一个Integer对象返回

知道这个,你就能很好地理解下面的各种情况了。

Integer使用==详解

int int1 = 128;
//以下是创建了Integer对象
Integer integer1 = 128;
Integer integer1a = 128;
Integer integer2 = new Integer(128);
Integer integer3 = Integer.valueOf(128);
Integer integer4 = Integer.valueOf("128");
//以下是返回了数池中的缓存值
Integer integer5 = 127;
Integer integer5a = 127;
Integer integer7 = Integer.valueOf(127);
//int跟Integer比较
System.out.println(int1 == integer1);//true
System.out.println(int1 == integer2);//true
System.out.println(int1 == integer3);//true
//Integer间比较
System.out.println(integer1 == integer2);//false
System.out.println(integer1 == integer3);//false
System.out.println(integer1 == integer1a);//false
System.out.println(integer5 == integer5a);//true

可以看出在数值相同的情况下

int==任何一种方式创建的Integer,返回的都是true,这是由于Integer跟int比较时会自动拆箱为int类型,两个int类型比较的就是数值。关于Integer自动拆装箱的详细内容,这里推荐别人的一篇文章:http://t.csdn.cn/4Gyqw

Integer==Integer,则比较复杂,需要看是哪种方式创建的Integer,并且value是否在-128至127之间。

如果是new的Integer,返回的必定是对象,==是比较引用,一般返回false。

非new的Integer,value在-128至127之间,返回的是值,否则返回对象。

总结

数值相等的情况下,==返回true还是false呢?

  • int类型跟Integer(任何一种),返回true。
  • Integer之间
    • new与new:返回false
    • new与非new:返回false
    • 非new与非new
      • -128至127之间:返回true
      • 范围之外:返回false

对于Integer的比较来说,我们更多时候关注的是数值是否相同,这时候就不应该使用双等号来比较,而是使用equals()方法。

若有错误,恳请在评论区指正!欢迎大家友好交流!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值