【问题标题】:What really happens inside equals(), hashcode() and compare() method?在 equals()、hashcode() 和 compare() 方法中到底发生了什么?
【发布时间】:2016-03-25 08:59:13
【问题描述】:

我真的对 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;
        }

    }

[edit 1]疑问1:每个比较的真正含义是什么?

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

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

[edit 2] 疑问2:是要比较List中的两个adjusent对象还是发生其他事情,它在内部做了什么?

【问题讨论】:

  • “我真的很困惑”是一种心态,而不是一个问题。如果你在这里需要帮助,你必须提出一个精确的问题。如果您不能这样做,这不适合您。你最好咨询一本书和你的老师。
  • 请将代码中使用列表的部分贴出来。
  • 我没有在任何地方使用它,它只是为了理解目的。考虑到我在做 employeeList.sort();真正的 compare() 行为如何?

标签: java collections comparator


【解决方案1】:

this == obj 检查当前对象是否与另一个对象SAME

如果它们是同一个Object,当然它们也是“相等的”。

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

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

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

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

两个具有相同姓名的员工(忽略不同的情况),将被视为同一员工进行排序操作。

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

【讨论】:

  • 我知道 compareToIgnoreCase 方法 Employee a 和 Employee b 与我要排序的列表相比是什么?
  • 排序算法,不管是什么,都需要比较列表中的员工进行排序。 a 和 b 是算法需要比较的列表中的两个员工
【解决方案2】:

Doubt1 :那么这里到底发生了什么,我知道这是指当前对象到当前对象,为什么我们要在等于中比较 this==obj。每个比较的真正含义是什么?

当你做this == obj时,你基本上是检查this对象的引用和被比较的对象,即obj是否相同。

如果您正在调用equals(),那么它会根据您覆盖的equals() 方法比较this 对象和比较对象(即obj)是否相同。例如,this.equals(obj) 将返回 true 当且仅当它满足 equals() 方法中的条件。

由于您已经覆盖了hashCode() 方法,因此哈希码计算将由您覆盖的方法完成。

hashCode()equals() 之间有一个合同,如果您要覆盖一个合同,那么您也应该覆盖另一个合同,否则不能保证按预期工作。

疑问2:compareToIgnoreCase() 是什么意思?它会比较 List 中的两个辅助对象还是发生其他事情,它在内部做了什么?

这只是两个对象成员的普通字符串比较。在这种情况下,它将为员工 a 和员工 b 比较 Employee 对象的 name 成员。

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

fooBar
FooBAR

在这里,compareTo() 将返回 false,但 compareToIgnoreCase() 将返回 true

【讨论】:

  • 请检查编辑。我的意思是 fooBar 和 FooBar 来自哪里,这些相邻的项目是否来自列表?我不明白后台发生的比较。
  • 这不是 == 的作用。
  • @user2004685 因为你不知道 ref1 == ref2 做了什么
  • 调用 equals 时,您也没有比较 hashCodes。这个答案还是错的
  • @piechuckerr 当您实现Comparator 时,Java 可能会在对列表进行排序或决定优先级(如果您正在实现 PriorityQueues)等时调用它。它采用 2 个对象和然后决定(在这种情况下基于 name 字符串)应该先选择哪个。
猜你喜欢
  • 2013-07-28
  • 1970-01-01
  • 1970-01-01
  • 2011-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多