10年老鸟竟不知道Integer如何比较大小

简介: 10年老鸟竟不知道Integer如何比较大小

前言


工作多年,最近在项目中一个地方Integer比较大小,竟然踩坑了。

那么你知道Integer比较大小的正确写法吗?


一、错误说明


先看一下下面这个demo,大家猜下,是相等还是不相等?

@Test
public void integerTest(){
    Integer  status = 1;
    if("1".equals(status)){
        System.out.println("相等");
    }else{
        System.out.println("不相等");
    }
}

执行结果:

42.png

原因分析:

equals方法的调用者“1”是一个字符串对象,所以这里走的是String对象的equals方法,而不是Integer对象的equals方法。


String对象的equals方法源码:

public boolean equals(Object anObject) {
        if (this == anObject) {
            return 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;
    }


说明:

参数如果不是String类型,直接返回false。


二、优化一


那么正确写法是什么?


大部分人可能想到了Integer对象status前置,如下

@Test
public void integerTest2(){
    Integer  status = 1;
    if(status.equals(1)){
        System.out.println("相等");
    }else{
        System.out.println("不相等");
    }
}


执行结果:

41.png

分析:

结果确实正确。但是大家有想过一点吗,由于程序中,Integer对象是可以为null的。一个为null的对象是不能调用任何方法的,否则就会出现空指针异常。

40.png


三、阿里规约的相关说明


这点大家应该都想到了String对象的等值比较,阿里的java规范中也提到的,尽量使用非空常量对象作为方法的调用方。

39.png


四、Integer等值比较优化


Integer等值比较优化

@Test
    public void integerTest2(){
        Integer  status = null;
        if(Integer.valueOf(1).equals(status)){
            System.out.println("相等");
        }else{
            System.out.println("不相等");
        }
    }

执行结果:

38.png

这样,即使变量status为空,也不会影响equals方法的比较结果。


五、相关建议


1、包装类型等值比较必须使用equals,只有基本类型等值比较使用==

2、调用equals方法时,使用常量和确定有值的对象作为方法的调用方,减少空指针异常。

3、进行equals等值判断的值,推荐采用常量类或枚举类进行封装。

4、偷懒的写法:Integer.valueOf(1).equals(status)。将基本类型转成包装类后再使用equals比较。


六、Integer的缓存说明


@Test
    public void integerTest2(){
        Integer  integer1 = 3;
        Integer  integer2 = 3;
        if(integer1 == integer2){
            System.out.println("相等");
        }else{
            System.out.println("不相等");
        }
          integer1 = new Integer("3");
          integer2 = new Integer("3");
            if(integer1 == integer2){
                System.out.println("相等");
            }else{
                System.out.println("不相等");
            }
        integer1 = 128;
        integer2 = 128;
        if(integer1 == integer2){
            System.out.println("相等");
        }else{
            System.out.println("不相等");
        }
    }


执行结果:


相等
不相等
不相等


说明:

首先说明一点,Integer这个缓存机制,其实对我们写代码来说基本没什么影响,只是对底层数据存储的内存优化。

实际项目开发过程中,Integer的等值比较必须采用equals,而不能使用==。


执行结果说明:

由于==实际比较的是对象的内存地址,而Integer在-128 至 127 范围内采用Integer integer1 = 3这样的方式复制时,会复用已经缓存的对象,所以相等。


采用new的方式会重新声明对象会分配新的内存地址,不使用缓存对象,所以不相等。


超过128的对象不会使用缓存对象,地址都重新分配,所以不相等。


总结


1.包装类型等值比较必须使用equals,基本类型等值比较使用==


2.Integer的缓存范围在-128~127(默认),知道就好,项目中禁止使用 ==来比较Integer的大小。


3、基本类型需要转为包装类型再调用equals方法比较大小


Integer.valueOf(1).equals(status)


4、为了避免魔法值,对参与equals等值比较的值,尽量采用常量类或枚举类进行封装。

目录
相关文章
|
6月前
|
缓存
【面试知识点】关于Integer和Int的比较
【面试知识点】关于Integer和Int的比较
|
5月前
|
缓存 安全 Java
必知的技术知识:Integer引发的思考
必知的技术知识:Integer引发的思考
27 0
|
存储 缓存 安全
Java基础知识面试查漏补缺之String
Java基础知识面试查漏补缺之String
99 2
|
6月前
|
存储 算法 安全
【数据结构与算法初学者指南】【冲击蓝桥篇】String与StringBuilder的区别和用法
【数据结构与算法初学者指南】【冲击蓝桥篇】String与StringBuilder的区别和用法
|
存储 C++ 容器
C++进阶之一篇文章教会你什么是map和set(下)
6.set观察器和操作成员函数 Observers key_comp(返回键的比较对象): key_compare key_comp() const;
|
存储 自然语言处理 算法
C++进阶之一篇文章教会你什么是map和set(上)
序列式容器和关联式容器 序列式容器: 序列式容器是一组用于存储数据的容器,其中的数据按照它们在容器中的位置进行存储和访问。序列式容器提供了对元素的线性访问和操作,其主要特点包括:
|
存储 安全 JavaScript
金九银十,收下这份 Java String 面试题
金九银十,收下这份 Java String 面试题
136 0
金九银十,收下这份 Java String 面试题
|
编译器 C语言 C++
【C++】一文带你吃透string的模拟实现 (万字详解)(下)
【C++】一文带你吃透string的模拟实现 (万字详解)(下)
【C++】一文带你吃透string的模拟实现 (万字详解)(下)
|
存储 编译器 C++
【C++】一文带你吃透string的模拟实现 (万字详解)(上)
【C++】一文带你吃透string的模拟实现 (万字详解)(上)
109 0
【C++】一文带你吃透string的模拟实现 (万字详解)(上)