- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
如果我重写类中的任何一个方法,它必须确保如果A.equals(B) == true
then A.hashCode() == B.hashCode
也必须为真。
谁能告诉我一个简单的例子,如果违反了这一点,它会导致问题吗?我觉得跟你用那个class作为Hashmap的key类型有关系吗?
最佳答案
当然:
public class Test {
private final int m, n;
public Test(int m, int n) {
this.m = m;
this.n = n;
}
public int hashCode() { return n * m; }
public boolean equals(Object ob) {
if (ob.getClass() != Test.class) return false;
Test other = (Test)ob;
return m == other.m;
}
}
与:
Set<Test> set = new HashSet<Test>();
set.put(new Test(3,4));
boolean b = set.contains(new Test(3, 10)); // false
从技术上讲,这应该是正确的,因为在这两种情况下 m == 3。
一般来说,HashMap 是这样工作的:它有数量可变的通常称为“桶”的东西。桶的数量会随时间变化(随着条目的添加和删除),但它始终是 2 的幂。
假设给定的 HashMap
有 16 个桶。当您调用 put() 添加条目时,会计算键的 hashCode(),然后根据桶的大小采用掩码。如果您(按位)AND hashCode() 与 15 (0x0F),您将获得最后 4 位,等于 0 到 15 之间的数字:
int factor = 4;
int buckets = 1 << (factor-1) - 1; // 16
int mask = buckets - 1; // 15
int code = key.hashCode();
int dest = code & mask; // a number from 0 to 15 inclusive
现在,如果该存储桶中已经有一个条目,您就会遇到所谓的碰撞。有多种方法可以处理此问题,但 HashMap 使用的方法(并且可能是最常见的一种)是分桶。所有具有相同掩码哈希码的条目都放在某种列表中。
所以要查找给定的键是否已经在映射中:
查看桶是一个线性 (O(n)) 操作,但它在一个小子集上。哈希码桶的确定本质上是恒定的 (O(1))。如果桶足够小,那么访问 HashMap 通常被描述为“接近 O(1)”。
您可以对此进行一些观察。
首先,如果您有一堆对象都返回 42 作为它们的哈希码,HashMap
仍然可以工作,但它将作为一个昂贵的列表运行。访问将是 O(n)(因为无论桶的数量如何,所有内容都将在同一个桶中)。事实上,我在一次采访中被问到过这个问题。
其次,回到你原来的观点,如果两个对象相等(意思是 a.equals(b) == b.equals(a) == true
)但是有不同的哈希码然后HashMap
将(可能)查找错误的存储桶,从而导致不可预测和未定义的行为。
关于java - 在Java中,为什么equals()和hashCode()必须保持一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1678205/
class UserScoring implements Comparable { User user; int score; UserScoring(
当重写 Java 中的 equals() 和 hashcode() 方法时,为什么不经常使用它: public int hashCode() { return (int) this.hashC
给定java Object#hashCode文档快照: As much as is reasonably practical, the hashCode method defined by class
下面的代码(sign.hashCode())是给我签名的hashCode还是内存中对象的hash? try { PackageInfo packageInfo = getPackageMana
考虑: String[] segments = {"asdf", "qwerty", "blahblah", "alongerstring", "w349fe3434"}; String fullSt
在审查大型代码库时,我经常遇到这样的情况: @Override public int hashCode() { return someFieldValue.hashCode(); } 程序员不
在以下情况下,与下面的函数发生 HashCode 冲突的可能性有多大。 key[0]、key[1]、key[2]、key[3] 的随机整数值 使用具有以下约束的随机键值 键[0] <1,000,000
从 Java 7 开始,我们有了 o.hashCode(); Objects.hashCode(o); Objects.hash(o); 前两个与空检查大致相同,但最后一个是什么? When a si
这个问题已经有答案了: Objects.hash() vs Objects.hashCode(), clarification needed (3 个回答) 已关闭 6 年前。 一个简单、简短的问题:
我是否需要使用super.hashcode()来计算this.hashcode()? IDE(例如 IntelliJ Idea)可以生成 equals 和 hashcode。它可以使用 java.ut
class A { } class B extends A { void m1(){ System.out.println(this.hashCode());
我查看了Arrays.hashCode(char[] c)的源代码 我不太确定它适用的算法是否在所有情况下都能正常工作。 public static int hashCode(int a[])
我有两个表具有一对一的关系,如下所示: @Entity @Data @NoArgsConstructor @AllArgsConstructor public class Book { @Id
为什么stringObject的hashcode是我提供的字符串? String s = new String(); // here the hascode is 0. 但是当我获得我创建的某个对象的
public abstract class HolidayPackageVariant { private HolidayPackage holidayPackage; private String
这两个代码片段有什么区别? 片段 1: Object o = new Object(); int i = Objects.hashCode(o); 片段 2: Object o = new Objec
在 Java 8 中有一个类 java.util.Objects,其中包含 hashCode() 方法。同时 Google Guava 19 包含 com.google.common.base.Obj
我的一个类(class)中有以下方法。它只是 HashMap 的公共(public)包装器(名为 teamOfPlayer,具有 Player 对象的键和 Integer 对象的值),仅此而已。 pu
我在这里做错了什么? @Override public int hashCode() { HashCodeBuilder has
我有以下程序。 Employee employee1 = new Employee("Raghav1", 101); Employee employee2 = new Employee("Raghav
我是一名优秀的程序员,十分优秀!