• List.contains()与自动拆箱


    最近项目引入sonarQube这种代码静态检查的东东,以前没有人力和精力review,现在只要扫描一下项目,就发现很多有趣的地方.

    有这么一段代码:

    List<Long> list = Lists.newArrayList();
    Long a = 1L;
    if(list.contains(a.longValue()){
     .....
    }

    这里用到了一个手动拆箱,当然以上的代码只是个示例,但是总体的逻辑是不变的,那么这个手动拆箱,实际上是这段代码的原作者害怕出现Long==Long这种不会触发自动拆箱的问题.

    这里简单说一下:

    Long a1 = 1l;
    Long a2 = 1l
    System.out.println(a1==a2); //虽然相等但是没有触发自动拆箱,实际上这里是由于Long的缓存机制,的确引用的是同一个对象
    Long b1=new Long(1);
    Long b2=new Long(1);
    System.out.println(b1==b2); //没有触发拆箱,不是同一个对象,故不相等

    所以为了确保触发自动拆箱,故原作者自己手动拆箱达成Long==long这种满足自动拆箱原则的条件.

    但是呢,sonarQube提示这个其实没必要,所以看一下List.contains()这个方法到底是如何实现的好了:

        public boolean contains(Object o) {
            return indexOf(o) >= 0;
        }
    
        public int indexOf(Object o) {
            if (o == null) {
                for (int i = 0; i < size; i++)
                    if (elementData[i]==null)
                        return i;
            } else {
                for (int i = 0; i < size; i++)
                    if (o.equals(elementData[i]))
                        return i;
            }
            return -1;
        }

    发现其实调用的是equals方法,那么Long的equals方法实现:

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

    可以看到其实已经拆箱比较了,故原作者其实是想多了,这里无需手动拆箱直接调用即可,即原例子中直接 list.contains(a)即可判断.

  • 相关阅读:
    Oracle数据库的dual表的作用
    数据库中CASE函数和Oracle的DECODE函数的用法
    Oracle数据库中,通过function的方式建立自增字段
    Java学习(十三):抽象类和接口的区别,各自的优缺点
    Java学习(十八):二叉树的三种递归遍历
    Sublime工具插件安装
    sizeof和strlen
    I2C接口的EEPROM操作
    关于窗口看门狗
    关于指针传入函数
  • 原文地址:https://www.cnblogs.com/chyu/p/9035925.html
Copyright © 2020-2023  润新知