zoukankan      html  css  js  c++  java
  • equals、==和hashCode

    equals和==

      ==可以用于基本类型和引用类型:当用于基本类型时,比较值是否相同当用于引用类型时,比较的是所指向的对象的地址是否相同。如果有包装类型,则先将包装类型转换为基本类型再比较值是否相等。当两边都为包装类型时,即为对象,比较的是地址。

      “==”和“!=”比较的是地址,指一个new()出来的地址。

      equals不能作用于基本数据类型的变量,如果没有对equals重写,则比较的的是引用类型的变量所指向的对象的地址。String类的equals方法重写了是比较值。

      下面是String的equals的源码:可以看出String是将字符串拆成字符挨个比较。

    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;
    }

     

      Integer的equals()方法如下:是Integer的实例且value值也相等的情况下返回true,其他返回false。

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

      两个基本型的封装型进行equals()比较,首先equals()会比较类型,如果类型相同,则继续比较值,如果值也相同,返回true。

      基本型和基本封装型进行“==”运算符的比较,基本型封装型会自动拆箱变为基本型后再进行比较。

     

    equals和hashCode

      参考博客

      http://doc.orz520.com/a/doc/2014/0527/2019620.html?from=haosou

           http://www.importnew.com/20381.html

    equals

      默认情况(没有覆盖equals方法)下equals方法都是调用Object类的equals方法,而Object的equals方法主要用于判断对象的内存地址引用是不是同一个地址(是不是同一个对象)。要是类中覆盖了equals方法,那么就要根据具体的代码来确定equals方法的作用了,覆盖后一般都是通过对象的内容是否相等来判断对象是否相等。

    hashCode

      public native int hashCode();

      它是一个本地方法,它的实现与本地机器有关,这里我们暂且认为他返回的是对象存储的物理位置(实际上不是,这里写是便于理解)。

            hashcode方法只有在集合中用到。

      hashCode在扮演的角色为寻域(寻找某个对象在集合中区域位置)。hashCode可以将集合分成若干个区域,每个对象都可以计算出他们的hash码,可以将hash码分组,每个分组对应着某个存储区域,根据一个对象的hash码就可以确定该对象所存储区域,这样就大大减少查询匹配元素的数量,提高了查询效率。

      对于HashMap、HashSet、HashTable而言,它变得异常重要。所以在使用HashMap、HashSet、HashTable时一定要注意hashCode。

      将对象放入到集合中时,首先判断要放入对象的hashcode值与集合中的任意一个元素的hashcode值是否相等,如果不相等直接将该对象放入集合中。如果hashcode值相等,然后再通过equals方法判断要放入对象与集合中的任意一个对象是否相等,如果equals判断不相等,直接将该元素放入到集合中,否则判断对象的equals是否相等。这样处理,当我们存入大量元素时就可以大大减少调用equals()方法的次数,极大地提高了效率。

     

    注意

    两个对象的值相同(x.equals(y) == true),但是却可有不同的hashCode。

    原因:

      如果对象保存在HashSet或HashMap中,他们的equals值相等,那么他们的hashCode值必须相等。

      如果不是保存在HashSet或HashMap中,则与hashCode没有什么关系,这时hashCode值可以不相等,例如ArrayList存储的对象就不用实现hashCode,但是通常都回去实现。

     

    Integer类型与int类型的==比较

    参考博客:

            http://blog.csdn.net/sgls652709/article/details/49079767

    举个例子来说明:

    Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
    System.out.println(f1 == f2); //true
    System.out.println(f3 == f4); //false

      同样都是Integer类型的比较,为什么用100比的结果是true,150比的结果是false。

      给一个Integer赋予一个int类型的时候,会调用Integer的静态方法valueOf。

    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);
        }

       valueof()是把int 转化成Integer对象类型;(延伸:intValue()是把Integer对象类型变成int的基础数据类型

      在IntegerCache中cache数组初始化如下,存入了-128 - 127的值。

       从上面我们可以知道给Interger 赋予的int数值在-128 - 127的时候,直接从cache中获取,这些cache引用对Integer对象地址是不变的,但是不在这个范围内的数字,则new Integer(i) 这个地址是新的地址,不可能一样的。

      使用Integer a = 1;Integer a = Integer.valueOf(1); 在值介于-128127直接时,作为基本类型。

      使用Integer a = new Integer(1); 时,无论值是多少,都作为对象。

    延伸

      java中还有与Integer类似的是Long,它也有一个缓存,在区间[-128,127]范围内获取缓存的值,而Long与long比较的时候先转换成long类型再做值的比较

      Double类型,它没有缓存,但是当Double与double比较的时候会先转换成double类型,再做值的比较

     

  • 相关阅读:
    《.NET内存管理宝典 》(Pro .NET Memory Management) 阅读指南
    《.NET内存管理宝典 》(Pro .NET Memory Management) 阅读指南
    《.NET内存管理宝典 》(Pro .NET Memory Management) 阅读指南
    使用Jasmine和karma对传统js进行单元测试
    《.NET内存管理宝典 》(Pro .NET Memory Management) 阅读指南
    《.NET内存管理宝典 》(Pro .NET Memory Management) 阅读指南
    nginx 基于IP的多虚拟主机配置
    Shiro 框架的MD5加密算法实现原理
    项目实战:Qt+OSG三维点云引擎(支持原点,缩放,单独轴或者组合多轴拽拖旋转,支持导入点云文件)
    实用技巧:阿里云服务器建立公网物联网服务器(解决阿里云服务器端口,公网连接不上的问题)
  • 原文地址:https://www.cnblogs.com/ghq120/p/8278690.html
Copyright © 2011-2022 走看看