• 关于判断对象是否相等的问题


    0. 哈希码值hashCode


    哈希码值(hashCode),也称散列码值是一个通过哈希散列算法得到的数据值,在java中可通过int hashCode()返回某对象的哈希码值。

    这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode()函数。

    hashCode有以下特点

    1. 哈希散列算法对于同一个对象在同一次程序执行过程中,调用多次hashcode方法得到的值必须是一致的;
    2. 哈希散列算法对于不同对象计算出的哈希码结果相同的概率非常小,可认为是一一对应的单射。即:每个对象的哈希码值都不同
    3. 因着以上两点可以判断两个对象是否是同一个对象。

    hashCode的计算方式:

    1. 字符串:(s[0]*31^{(n-1)}+s[1]*31^{(n-2)}+...+s[n-1]^0)

      其中s[i]是字符串的第i个字符,n是字符串长度。空字符串的哈希值为0;

    2. 八大基本数据类型哈希值是固定:

      1. 整型:就是值本身
      2. 浮点型:通过固定的计算模式计算得到
      3. 字符型:是该字符对应的ASCII码值
      4. 布尔型:哈希值是固定的 true:1231 false:1237

     

    1. ==和equals


    == : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象。

    • 基本数据类型 == 比较的是值。
    • 引用数据类型 == 比较的是内存地址

    equals() : 它的作用也是判断两个对象的地址是不是相等。但它一般有两种使用情况:

    • 情况1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。(object的equals方法是比较的对象的内存地址。)

    • 情况2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来两个对象的内容相等;若它们的内容相等,则返回 true (即,认为这两个对象相等)。此时,标准流程如下:

      1. 先判断地址值是否相同,同则直接true。
      2. 判断传入参数是否为null,是则直接false。
      3. 判断两个对象是否同一类型(利用getClass()),如果不是则直接false。
      4. 进行每个属性的一一判断
        1. 基本数据类型用==
        2. 引用数据类型用equals
      //重写equals案例
      class Person{
          String name;
          int age;
          public boolean equals(Object obj){
              if(this==obj) return true;//同一个对象
              if(obj==null) return false;//空指针
              if(this.getClass()!=obj.getClass()) return false;
      
              //在方法参数中向上造型了,隐蔽了其中的子类属性
              //必须要再向下造型,方可调用
              Person person = (Person)obj;
      
              //比较第一个属性
              if(this.name==null){
                  if(person.name!=null){
                      return false;
                  }
              }else if(this.name.equals(person.name)){
                  return false;
              }
              //比较第二个属性
              if(this.age!=person.age) return false;
              //到此为止,必然相同
              return true;
          }
      }
      
      

    【注】地址值实际就是该对象的哈希码值转为16进制的字符串形式。

     

    2. HashCode与equals的相关规定


    1. 如果两个对象相等,则hashcode一定也是相同的。
    2. 两个对象相等,对两个对象分别调用equals方法都返回true
    3. 两个对象有相同的hashcode值,它们也不一定是相等的(虽然概率极小)
    4. hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)

     

    3.【引】HashSet如何检查重复?


    当把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与其他已经加入的对象的 hashcode 值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。

    但是如果发现有相同 hashcode 值的对象,这时会调用 equals()方法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就会覆盖。如果不同的话,就会重新散列到其他位置。

  • 相关阅读:
    扯一下关于魔兽改键的蛋
    Emacs23.3在ubuntu10.10下的手动编译与安装
    GRUB2英文文档的部分翻译
    WinForm中Crossthread operation not valid错误的解决方法
    C# 嵌入式资源
    raster配准
    excel vba 玫瑰图 风速 风向
    使用UserControl好处
    How does ArcSDE use Oracle Spatial? arcsde怎么使用oracle spatial
    信息抽取的定义(definition of information extraction)
  • 原文地址:https://www.cnblogs.com/juzhuxiaozhu/p/13232974.html
Copyright © 2020-2023  润新知