zoukankan      html  css  js  c++  java
  • JavaSE-28 hashCode()方法、equals()方法和==相关概念

    • 概述

    Java中,Object类是所有类的基类:如果一个类没有明确继承其他已定义的类,则默认继承Object类。

    Object类提供了以下方法,对于其他方法,请参考前期专题描述。

     

    hashCode()方法、equals()方法和”==“通常在进行对象比较的时候容易引起混淆。

    对于 hashCode()方法、equals()方法而言,在使用的时候需要注意是否重写了该方法;String类重写了这两个方法,需要了解重写的内容。以下分别进行详细叙述。

     

    • hashCode()方法

    在Object类中,hashCode()方法定义如下:

        public native int hashCode();
    

      该方法是native修饰的本地方法,返回一个描述该对象的int类型数据,也称为哈希码值。

    Java没有提供相应实现类,由native接口调用相应的C++方法实现。方法实现可以参考openjdk相应C++代码。

    JDK1.6API对该值的描述是:由 Object 类定义的 hashCode 方法会针对不同的对象返回不同的整数。一般是通过将该对象的内部地址转换成一个整数来实现的。

    hashCode()方法的主要作用:为了提高访问哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。

    hashCode 方法的常规协定:

      1. 在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必定一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。程序多次执行,对象产生的hashCode可能是不同的。
      2. 如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
      3. 如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。

     总结以上三点:如果没有重写hashCode方法,对于同一个对象,在一个程序运行期间,所产生的hashCode是一样的。

     

    • equals()方法

     该方法用于比较是否是同一个对象,其源代码如下所示:

        public boolean equals(Object obj) {
            return (this == obj);
        }
    

      

    该方法中,使用“==”判断是否是同一个对象的引用,如果表示同一个对象,则返回true。

     

    • ==

    “==”是java中的比较运算符。对于基本数据类型,比较的是值的大小是否相等;对于引用类型,比较的是内存地址是否一致。

    • String类的hashCode()方法和equals()方法

    String类对这两个方法都进行了重写。

    String类hashCode()方法代码如下,在字符串中,hashCode生成的方式发生了变化:hashCode的值依赖于字符串内容。

        public int hashCode() {
            int h = hash;
            if (h == 0 && value.length > 0) {
                char val[] = value;
    
                for (int i = 0; i < value.length; i++) {
                    h = 31 * h + val[i];
                }
                hash = h;
            }
            return h;
        }
    

    String类equals()方法代码如下,重写的方法首先判断是否是同一个字符串对象,如果是,则返回true,如果不是,则对两个字符串对象的内容进行比较,完全一致则返回true。

     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对象比较示例

     示例代码:

    		String str1 = new String("Hello");
    		String str2 = new String("Hello");
    		// 判断是否是同一个对象
    		System.out.println(str1 == str2);
    		// 判断字符串内容是否一致
    		System.out.println(str1.equals(str2));
    		// hashCode是否一致
    		System.out.println(str1.hashCode() + "," + str2.hashCode());
    		// System.identityHashCode()方法根据对象内存地址返回hashCode的值,不同对象的结果值必定是不同的
    		System.out.println(System.identityHashCode(str1) + "," + System.identityHashCode(str2));
    

      输出结果:

    false
    true
    69609650,69609650
    118352462,1550089733
    

      

    由该例子可以看出,对于字符串类型数据,改写后的hashCode方法,如果字符串对象所代代表的内容一致,则返回相同的hashCode,这对于存储String是合理的。

    Java使用散列集合存储对象,通过类似key的方式访问对象,可以认为key即是hashCode,对于字符串类型,如果字符串内容一致,则不需要进行重复存储,使用hashCode作为key方式访问字符串对象可以提高访问效率。否则使用用equals方法去遍历数据会降低程序效率。



    本博客文章未经许可,禁止转载和商业用途!

    如有疑问,请联系: 2083967667@qq.com


  • 相关阅读:
    经典数组排序方法------快速排序法
    经典数组排序方法------选择排序法,冒泡排序法
    两个非常好的bootstrap模板,外送大话设计模式!
    商场促销-策略模式(和简单工厂模式很像的哇) C#
    代码无错就是优?简单工厂模式 C#
    大话设计模式(C#)
    马加爵遗书 VS 药家鑫遗书
    GIT 常用命令
    Random快速产生相同随机数的原因及解决方案
    JSON WEB TOKEN,简单谈谈TOKEN的使用及在C#中的实现
  • 原文地址:https://www.cnblogs.com/rask/p/8460836.html
Copyright © 2011-2022 走看看