在equals(),hashcode()和compare()方法中真正发生了什么?

时间:2016-03-25 08:59:13

标签: java collections comparator

我对hashcode()和equals()方法的实现感到困惑。 这是代码的和平。

class Employee {

      int id;
      String name;

      public Employee(int id, String name) {
          super();
          this.id = id;
          this.name = name;
      }

        @Override
       public int hashCode() {
        final int prime = 3;
        int result = 1;
        result = (prime * result) + id;
        result = (prime * result) + ((name == null) ? 0 : name.hashCode());
        return result;
     } 

      @Override
      public boolean equals(Object obj) {
        Employee other = (Employee) obj;

              if (this == obj)
                    return true;

              if (obj == null)
                    return false;
              if (getClass() != obj.getClass())
                return false;

              if (id != other.id)
                return false;
              if (name == null) {
                if (other.name != null)
                            return false;
                } else if (!name.equals(other.name))
                          return false;
                return true;
        }

    }

[编辑1] 怀疑1 :每个比较真正意味着什么?

现在我已经实现了比较器接口及其方法。

  class EmpNameComparator implements Comparator<Employee> {
        @Override
       public int compare(Employee a, Employee b) {
              return a.name.compareToIgnoreCase(b.name);
       }
  }

[edit 2] Doubt2:是否要比较List&lt;&gt;中的两个辅助对象?或其他事情正在发生,它在内部做了什么?

2 个答案:

答案 0 :(得分:3)

this == obj检查当前对象是否是 SAME 对象。

如果它们是同一个对象,当然它们也是“平等的”。

compareToIgnoreCase比较两个String个对象,忽略大写/小写差异:

  

按字典顺序比较两个字符串,忽略大小写差异。   此方法返回一个整数,其符号是调用compareTo的整数   具有大小写差异的字符串的规范化版本   通过电话被淘汰了   每个上都有Character.toLowerCase(Character.toUpperCase(字符))   字符。

因此,当您使用自定义比较器对Employee列表进行排序时:

Collections.sort(employeeList, new EmpNameComparator());

两名具有相同名称(忽略不同案例)的员工将被视为排序操作的同一员工。

请注意,您无法判断 John 是否会出现在 joHn 之前,或者相反。

答案 1 :(得分:1)

  

疑惑1:那么这里真正发生了什么,我知道这是当前对象的当前对象,为什么我们在equals中比较这个== obj。每个比较真正意味着什么?

执行this == obj时,您基本上检查this对象的引用和比较对象,obj是否相同。

如果您正在调用equals(),那么它正在比较this对象与比较对象obj是否相同,或者基于您覆盖的equals()方法。例如,this.equals(obj)当且仅当它满足true方法中的条件时才会返回equals()

由于您已覆盖hashCode()方法,因此哈希代码计算将由重写方法完成。

hashCode()equals()之间存在合约,如果您要覆盖其中一个,那么您也应该覆盖其他合同,否则无法保证按预期工作。

  

疑问2:compareToIgnoreCase()是什么意思?是否要比较List&lt;&gt;中的两个辅助对象?或其他事情正在发生,它在内部做了什么?

这只是两个对象成员的正常String比较。在这种情况下,它将为员工a和员工b的name对象的Employee成员进行篡改。

compareTo()不同,compareToIgnoreCase()进行不区分大小写的比较,即使两个字符串不相同,也会返回true。例如,

fooBar
FooBAR

此处compareTo()将返回false,但compareToIgnoreCase()将返回true