• 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类型,再做值的比较

     

  • 相关阅读:
    linux poll 和 select
    linux测试 scullpipe 驱动
    linux进程唤醒的细节
    linux进程互斥等待
    linux 手动睡眠
    linux一个进程如何睡眠
    [POJ 2431]Expedition
    【MongoDB数据库】MongoDB 命令入门初探
    高速排序为什么快?
    [050] 微信公众平台开发入门视频教程已公布
  • 原文地址:https://www.cnblogs.com/ghq120/p/8278690.html
Copyright © 2020-2023  润新知