Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 映射和哈希代码_Java_Performance_Collections_Hashmap_Hashcode - Fatal编程技术网

Java 映射和哈希代码

Java 映射和哈希代码,java,performance,collections,hashmap,hashcode,Java,Performance,Collections,Hashmap,Hashcode,使基于哈希的集合的唯一哈希代码工作得更快的原因是什么?以及使哈希代码不可变的原因是什么 我读了它,但不明白,所以我读了一些其他资源,并以这个问题结束 谢谢。hashcode()基本上是一个将对象转换为数字的函数。对于基于哈希的集合,此数字用于帮助查找对象。如果此数字更改,则意味着基于哈希的集合可能错误地存储了对象,并且无法再检索该对象 散列值的唯一性允许在集合内部更均匀地分布对象,从而提高性能。如果所有内容都散列到相同的值(最坏情况),则性能可能会降低 提供了一个很好的阅读,这可能有助于解释其中

使基于哈希的集合的唯一哈希代码工作得更快的原因是什么?以及使哈希代码不可变的原因是什么

我读了它,但不明白,所以我读了一些其他资源,并以这个问题结束

谢谢。

hashcode()基本上是一个将对象转换为数字的函数。对于基于哈希的集合,此数字用于帮助查找对象。如果此数字更改,则意味着基于哈希的集合可能错误地存储了对象,并且无法再检索该对象

散列值的唯一性允许在集合内部更均匀地分布对象,从而提高性能。如果所有内容都散列到相同的值(最坏情况),则性能可能会降低


提供了一个很好的阅读,这可能有助于解释其中的一些问题。

哈希代码不要求是唯一的,它们只是冲突的可能性很低


至于散列码是不可变的,只有当一个对象将被用作
散列映射
中的键时,这才是必需的。散列代码告诉
HashMap
在哪里对bucket数组进行初始探测。如果某个键的哈希代码发生更改,则映射将不再在正确的bucket中查找,并且将无法找到条目。

这与哈希表中项目的存储方式有关。哈希表将使用元素的哈希代码来存储和检索它。在这里详细解释有点复杂,但您可以通过阅读本节了解它:

hashCode
是一种棘手的方法。它应该提供平等的简写(这是地图和集合所关心的)。如果地图中的许多对象共享相同的哈希代码,地图将必须经常检查
equals
,这通常要昂贵得多

检查javadoc中的
equals
——即使对于不可变的对象,该方法也很难正确使用,使用可变对象作为映射键只是自找麻烦(因为该对象是为其“旧”哈希代码存储的)

为什么散列搜索更快

假设您有一些唯一的对象作为值,并且有一个
字符串作为其键。每个关键点都应该是唯一的,这样在搜索关键点时,您可以找到它作为其值保存的相关对象

现在假设您有1000个这样的键值对,您希望搜索特定的键并检索其值。如果没有哈希,则需要将密钥与表中的所有条目进行比较,并查找密钥


但是使用散列,您可以对密钥进行散列,并在插入时将相应的对象放入某个bucket中。现在,当您想要搜索一个特定的键时,您想要搜索的键将被散列并确定其散列值。您可以直接转到该散列桶,选择您的对象,而不必搜索整个键条目。

散列代码不必是唯一的,但如果不同的对象具有不同的散列代码,则它们工作得更好

hashcodes的一个常见用途是存储和查看数据结构中的对象,如
HashMap
。这些集合将对象存储在“bucket”中,并且正在存储的对象的hashcode用于确定它存储在哪个bucket中。这加快了检索速度。查找对象时,
HashMap
不必查看所有对象,而是使用hashcode确定要查找的bucket,并且它只在该bucket中查找


你问过易变性。我认为您要问的是,存储在
HashMap
中的对象在映射中时不能发生变异,或者最好是对象不可变。原因是,一般来说,改变对象会改变其哈希代码。如果对象存储在
HashMap
中,则其hashcode将用于确定存储在哪个bucket中。如果该对象发生变异,其哈希代码将发生变化。如果在此时查找对象,则会产生不同的哈希代码。这可能会将
HashMap
指向错误的存储桶,因此即使对象以前存储在该
HashMap

中,也可能找不到该对象,只要您使用的是按索引(0,1,2…collection.size()-1)检索元素的集合,而不需要hashcode。然而,如果我们谈论的是像maps这样的关联集合,或者只是问collection
它是否包含一些元素,那么我们谈论的是昂贵的操作。

Hashcode类似于所提供对象的摘要。它是强大和独特的。哈希代码通常用于二进制比较。在每个集合成员的二进制级别哈希代码上进行比较并不像在每个对象的属性上进行比较那样昂贵(肯定不止一个操作)。哈希代码需要像指纹一样-一个实体-一个,并且是不可变的哈希代码。

哈希的基本思想是,如果要在集合中查找哈希代码与该集合中99%的对象不同的对象,只需检查哈希代码匹配的1%的对象。如果哈希代码与集合中99.9%的对象的哈希代码不同,则只需检查0.1%的对象。在许多情况下,即使一个集合有一百万个对象,一个典型对象的哈希代码也只能匹配其中很小的一部分(在许多情况下,不到一打)。因此,一次散列计算可以消除近一百万次比较的需要

请注意,哈希值不必绝对唯一,但如果有太多实例共享同一哈希代码,则性能可能会非常差。请注意,对性能重要的不是不同散列值的总数,而是它们“聚集”的程度。在一百万件物品的集合中搜索一个对象