在Java中,obj.hashCode()
返回一些值。这个哈希码在编程中有什么用?
答案 0 :(得分:192)
hashCode()
用于Hash
实施中的 bucketing ,例如HashMap
,HashTable
,HashSet
等。
从hashCode()
收到的值用作存储桶编号,用于存储集合/地图的元素。此存储桶编号是集合/映射中元素的地址。
执行contains()
时,它将获取元素的哈希码,然后查找哈希码指向的桶。如果在同一个桶中找到多个元素(多个对象可以具有相同的哈希码),则它使用equals()
方法来评估对象是否相等,然后确定contains()
是否为是或否,或者决定是否可以在集合中添加元素。
答案 1 :(得分:28)
来自Javadoc:
返回对象的哈希码值。支持此方法是为了哈希表的好处,例如java.util.Hashtable
提供的哈希表。
hashCode
的一般合同是:
每当在执行Java应用程序期间多次在同一对象上调用它时,hashCode
方法必须始终返回相同的整数,前提是不使用任何信息in equals比较对象被修改。从应用程序的一次执行到同一应用程序的另一次执行,该整数不需要保持一致。
如果两个对象根据equals(Object)
方法相等,则在两个对象中的每个对象上调用hashCode
方法必须生成相同的整数结果。
根据equals(java.lang.Object)
方法,如果两个对象不相等则 要求 ,则必须在两个对象中的每一个上调用hashCode
方法不同的整数结果。但是,程序员应该知道为不等对象生成不同的整数结果可能会提高哈希表的性能。
尽可能合理,Object类定义的hashCode方法确实为不同的对象返回不同的整数。 (这通常通过将对象的内部地址转换为整数来实现,但Java编程语言不需要此实现技术。)
答案 2 :(得分:12)
hashCode()
是一个获取对象并输出数值的函数。如果对象没有改变,对象的哈希码总是相同的。
需要存储对象的HashMap
,HashTable
,HashSet
等函数将使用其内部数组大小的hashCode
模数来选择& #34;记忆位置" (即数组位置)来存储对象。
在某些情况下可能会发生冲突(两个对象最终会使用相同的哈希码),当然,这需要仔细解决。
答案 3 :(得分:12)
hashCode()
返回的值是对象的哈希码,它是十六进制的对象内存地址。根据定义,如果两个对象相等,则它们的哈希码也必须相等。如果您覆盖
equals()
方法,则会更改两个对象的等效方式,并且对象的hashCode()
实现不再有效。因此,如果重写equals()方法,则还必须覆盖hashCode()
方法。
This answer is from the java SE 8 official tutorial documentation
答案 4 :(得分:7)
虽然hashcode对您的业务逻辑没有任何作用,但在大多数情况下我们必须处理它。因为当你的对象放入基于哈希的容器(HashSet,HashMap ......)时,容器会放置/获取元素的哈希码。
答案 5 :(得分:2)
hashCode
每当您覆盖equals()时,都还应该覆盖hashCode()。哈希 在将对象作为键存储在地图中时使用代码。
哈希码是一个数字,它将一个类的实例放入有限数量的类别中。 想象一下,我给了你一副扑克牌,我告诉你我要问你具体的 卡,我想尽快找回正确的卡。只要你想 准备,但是当我开始要求卡片时,我非常着急。你可能会做13堆 纸牌:所有A都放在一堆中,所有的A放在另一堆中,依此类推。这样的话 我要五颗心,你可以从堆中的四张卡中取出正确的卡 五岁以下。这肯定比遍及整个52张卡片要快!你可以 如果桌上有足够的空间,甚至可以堆52堆。
参考: OCP Oracle认证专业Java SE 8程序员II
答案 6 :(得分:1)
答案 7 :(得分:0)
hashCode()的用途之一是构建捕捉机制。 看这个例子:
class Point
{
public int x, y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
if (x != point.x) return false;
return y == point.y;
}
@Override
public int hashCode()
{
int result = x;
result = 31 * result + y;
return result;
}
class Line
{
public Point start, end;
public Line(Point start, Point end)
{
this.start = start;
this.end = end;
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Line line = (Line) o;
if (!start.equals(line.start)) return false;
return end.equals(line.end);
}
@Override
public int hashCode()
{
int result = start.hashCode();
result = 31 * result + end.hashCode();
return result;
}
}
class LineToPointAdapter implements Iterable<Point>
{
private static int count = 0;
private static Map<Integer, List<Point>> cache = new HashMap<>();
private int hash;
public LineToPointAdapter(Line line)
{
hash = line.hashCode();
if (cache.get(hash) != null) return; // we already have it
System.out.println(
String.format("%d: Generating points for line [%d,%d]-[%d,%d] (no caching)",
++count, line.start.x, line.start.y, line.end.x, line.end.y));
}
答案 8 :(得分:0)
哈希码是从任何对象生成的数字。
这是允许将对象快速存储/存储在哈希表中的原因。
想象以下简单的示例:
在您面前的桌子上。您有9个盒子,每个盒子都标有1到9的数字。您还可以在这些盒子中存储一堆完全不同的对象,但是一旦它们放在那里,您就需要能够尽快找到它们。>
您需要的是一种立即确定将每个对象放入哪个盒子的方法。它的工作原理类似于索引。您决定找到卷心菜,因此您要查找卷心菜所在的盒子,然后直接去那个盒子拿到它。
现在想像一下,您不想打扰索引,而是希望能够立即从对象中找出索引所在的框。
在示例中,让我们使用一种非常简单的方法进行操作-对象名称中的字母数。因此,白菜在第7栏中进入,豌豆在第3栏中进入,火箭在第6栏中进入,班卓琴在第5方框中,依此类推。
那犀牛呢?它有10个字符,因此我们将略微更改算法并“环绕”,以便在框1中放入10个字母的对象,在框2中放入11个字母,依此类推。那应该覆盖任何物体。
有时候,一个盒子里会有不止一个物体,但是如果您要寻找火箭,比较花生和火箭,要比检查一大堆白菜,豌豆,班卓琴和香蕉要快得多。犀牛糖。
那是一个哈希码。一种从对象获取数字以将其存储在哈希表中的方法。在Java中,哈希码可以是任何整数,每种对象类型都负责生成自己的整数。查找对象的“ hashCode”方法。
来源-here
答案 9 :(得分:-10)
给定类的hashCode方法可用于测试对象不等式,但是 对于该类,不是对象相等。
java.util.HashSet集合类使用hashCode方法对其进行分组 其中的元素设置为散列桶以便快速检索。