踩坑-Integer类型的整数比较大小

先划重点: Integer类型的整数比较数值大小用equals.()intValue(),尽量别用==去比较是否相等

之前没注意过Integer类型比较数值大小,一直在用 ==
某天,写的一段程序没跑通,才注意到这个问题


举个例子

    public static void main(String[] args) {
        Integer  a = 1 ;
        Integer  b = 1 ;
        System.out.println(a == b);
        System.out.println(a.equals(b));
        a = 1515;
        b = 1515;
        System.out.println(a == b);
        System.out.println(a.equals(b)); 
    }  
    结果:
    true
    true
    false
    true 

原因

  • Integer.valueOf()
    上述Integer类型在比较大小的时候调用了Integer.valueOf()方法,源码:

    /**
     * Returns an {@code Integer} instance representing the specified
     * {@code int} value.  If a new {@code Integer} instance is not
     * required, this method should generally be used in preference to
     * the constructor {@link #Integer(int)}, as this method is likely
     * to yield significantly better space and time performance by
     * caching frequently requested values.
     *
     * This method will always cache values in the range -128 to 127,
     * inclusive, and may cache other values outside of this range.
     *
     * @param  i an {@code int} value.
     * @return an {@code Integer} instance representing {@code i}.
     * @since  1.5
     */
    public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

-128到127之间的数,比较数值大小的时候用equals.() == 得到的结果是一样的,超出了这个范围,用 == 比较大小就相当于判断是否是同一个对象了。

  • equals
    来看看equals是咋工作的
/**
     * Compares this object to the specified object.  The result is
     * {@code true} if and only if the argument is not
     * {@code null} and is an {@code Integer} object that
     * contains the same {@code int} value as this object.
     *
     * @param   obj   the object to compare with.
     * @return  {@code true} if the objects are the same;
     *          {@code false} otherwise.
     */
    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

后续

附上看到的一个总结的比较好的例子

public static void main(String[] args) {
        // 两个new出来的Integer类型的数据比较,
        //相当于把new出来的地址作比较

        Integer a0 = new Integer(1);// 普通的堆中对象
        Integer b0 = new Integer(1);
        System.out.println("new出来的 " + "a0==b0 :" + (a0 == b0));
        System.out.println(a0);

        // 调用intValue方法得到其int值
        System.out.println("调用intValue " + "a0.intValue() == b0.intValue()" + 
        (a0.intValue() == b0.intValue()));

        // 把Integer类型的变量拆箱成int类型
        int c = 1;
        System.out.println("将Integer自动拆箱 " + "a0==c: " + (a0 == c));

        // 其实也是内存地址的比较
        Integer a1 = 30; // 自动装箱,如果在-128到127之间,则值存在常量池中
        Integer b1 = 30;
        System.out.println("直接赋值的两个Integer的比较" + 
        "a2 == b2: "+ (a1 == b1));

        Integer a2 = 30;
        Integer b2 = 40;
        System.out.println("直接赋值的两个Integer的比较 " + 
        "a6==b6: " + (a2 == b2));

        Integer a3 = 128;
        Integer b3 = 128;
        System.out.println("直接赋值的两个Integer的比较 " + 
        "a5 == b5: " + (a3 == b3));

        Integer a4 = 412;
        Integer b4 = 412;
        System.out.println("直接赋值的两个Integer的比较 " + 
        "a4 == b4: " + (a4 == b4));
        // 从这里看出,当给Integer直接赋值时,
        //如果在-128到127之间相等的话,它们会共用一块内存
        // 而超过这个范围,则对应的Integer对象有多少个就开辟多少个

        System.out.println("调用intValue " + "a4.intValue() == b4.intValue(): " 
        + (a4.intValue() == b4.intValue()));
    }

结果:

new出来的 a0==b0 :false
1
调用intValue a0.intValue() == b0.intValue()true
将Integer自动拆箱 a0==c: true
直接赋值的两个Integer的比较a2 == b2: true
直接赋值的两个Integer的比较 a6==b6: false
直接赋值的两个Integer的比较 a5 == b5: false
直接赋值的两个Integer的比较 a4 == b4: false
调用intValue a4.intValue() == b4.intValue(): true
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值