提交 d6fe0c5a 编写于 作者: W wizardforcel

2020-06-12 17:28:03

上级 2309eb13
......@@ -31,12 +31,12 @@
* HashMap 如何存储键值对?
* HashMap 如何解决冲突?
* HashMap 中如何使用 hashCode()和 equals()方法?
* 密钥的随机/固定 hashCode()值的影响?
* 的随机/固定 hashCode()值的影响?
* 在多线程环境中使用 HashMap?
#### 1.4 [为 HashMap 设计一个好的密钥](//howtodoinjava.com/java/collections/how-to-design-a-good-key-for-hashmap/)
#### 1.4 [为 HashMap 设计一个好的](//howtodoinjava.com/java/collections/how-to-design-a-good-key-for-hashmap/)
因此,您现在知道`HashMap`的工作原理吗? 现在了解有关为`HashMap`设计一个好的密钥的信息。 这是测试您是否正确理解 HashMap 内部工作的一种好方法。 这将帮助您回答以下问题:
因此,您现在知道`HashMap`的工作原理吗? 现在了解有关为`HashMap`设计一个好的的信息。 这是测试您是否正确理解 HashMap 内部工作的一种好方法。 这将帮助您回答以下问题:
* 为什么`String`是 HashMap 的好钥匙?
* 您将如何设计用作键的类?
......
......@@ -472,7 +472,7 @@ for(char c : passwordChars) {
## 20.为什么 String 是 Java 中流行的 HashMap 键?
在 Java 中,必须在`Map`中使用的密钥是不可变的,并且应遵循`equals()``hashCode()`方法之间的约定。 `String`类满足这两个条件。
在 Java 中,必须在`Map`中使用的是不可变的,并且应遵循`equals()``hashCode()`方法之间的约定。 `String`类满足这两个条件。
另外,String 类提供了许多有用的方法来比较,排序,标记化或小写。 在`Map`上执行 CRUD 操作时可以使用这些方法。 这使它成为在`Map`中使用而不是创建自己的类的非常有用的类。
......
......@@ -135,7 +135,7 @@ final int hash;
当某人尝试将键值对存储在`HashMap`中时,会发生以下情况:
* 首先,检查键对象是否为空。 如果 key 为 null,则值存储在 table [0]位置。 因为 null 的哈希码始终为 0。
* 然后,下一步,通过调用密钥`hashCode()`方法,使用键的哈希码计算哈希值。 该哈希值用于计算数组中用于存储`Entry`对象的索引。 JDK 设计人员很好地假设可能存在一些编写不当的`hashCode()`函数,它们可能返回非常高或很低的哈希码值。 为解决此问题,他们引入了另一个`hash()`函数,并将对象的哈希码传递给此`hash()`函数,以将哈希值带入数组索引大小的范围内。
* 然后,下一步,通过调用`hashCode()`方法,使用键的哈希码计算哈希值。 该哈希值用于计算数组中用于存储`Entry`对象的索引。 JDK 设计人员很好地假设可能存在一些编写不当的`hashCode()`函数,它们可能返回非常高或很低的哈希码值。 为解决此问题,他们引入了另一个`hash()`函数,并将对象的哈希码传递给此`hash()`函数,以将哈希值带入数组索引大小的范围内。
* 现在,调用`indexFor(hash, table.length)`函数来计算用于存储 Entry 对象的精确索引位置。
* Here comes the main part. Now, as we know that two unequal objects can have same hash code value, how two different objects will be stored in same array location [called bucket]. Answer is `LinkedList`. If you remember, `Entry` class had an attribute “`next`”. This attribute always points to next object in chain. This is exactly the behavior of `LinkedList`.
......
......@@ -225,7 +225,7 @@ Map 接口是一种特殊的集合类型,它是**,用于存储键值对**。
**IdentityHashMap** 与 HashMap 相似,不同之处在于**在比较元素**时使用引用相等性。 IdentityHashMap 类不是一种广泛使用的 Map 实现。 尽管此类实现了 Map 接口,但它有意违反 Map 的一般协定,该协定要求在比较对象时必须使用 equals()方法。 IdentityHashMap 设计为仅在少数情况下使用,其中需要引用相等语义。
**WeakHashMap** 是 Map 接口**的实现,该接口仅存储对其键**的弱引用。 当不再在 WeakHashMap 外部引用键值对时,仅存储弱引用将允许对键值对进行垃圾回收。 该类主要用于与 equals 方法使用==运算符测试对象标识的键对象一起使用。 一旦丢弃了这样的密钥,就永远无法重新创建它,因此以后不可能在 WeakHashMap 中对该密钥进行查找,并且会惊讶地发现它的条目已被删除。
**WeakHashMap** 是 Map 接口**的实现,该接口仅存储对其键**的弱引用。 当不再在 WeakHashMap 外部引用键值对时,仅存储弱引用将允许对键值对进行垃圾回收。 该类主要用于与 equals 方法使用==运算符测试对象标识的键对象一起使用。 一旦丢弃了这样的键,就永远无法重新创建它,因此以后不可能在 WeakHashMap 中对该键进行查找,并且会惊讶地发现它的条目已被删除。
#### 13)解释 ConcurrentHashMap 吗? 怎么运行的?
......@@ -265,15 +265,15 @@ transient Entry[] table;
数组的索引是根据 Key 对象的哈希码计算的。 阅读更多链接主题。
#### 15)如何为哈希表设计一个好的密钥
#### 15)如何为哈希表设计一个好的
在回答`HashMap`如何工作后,通常会跟进另一个好问题。 好吧,最重要的约束是**,您将来必须能够取回值对象**。 否则,没有使用这种数据结构。 如果您了解 hashmap 的工作原理,将会发现它很大程度上取决于 Key 对象的 hashCode()和 equals()方法。
因此,好的密钥对象**必须一次又一次提供相同的 hashCode()**,无论它被获取了多少次。 同样,与 equals()方法比较时,相同的键**必须返回 true,而不同的键必须返回 false**
因此,好的对象**必须一次又一次提供相同的 hashCode()**,无论它被获取了多少次。 同样,与 equals()方法比较时,相同的键**必须返回 true,而不同的键必须返回 false**
因此,**不变类被认为是 HashMap 密钥**的最佳候选者。
因此,**不变类被认为是 HashMap **的最佳候选者。
阅读更多: [**如何为 HashMap 设计一个好的密钥?**](//howtodoinjava.com/java/collections/how-to-design-a-good-key-for-hashmap/ "How to design a good key for HashMap")
阅读更多: [**如何为 HashMap 设计一个好的?**](//howtodoinjava.com/java/collections/how-to-design-a-good-key-for-hashmap/ "How to design a good key for HashMap")
#### 16)Map 界面提供哪些不同的 Collection 视图?
......
......@@ -8,18 +8,18 @@
## HashMap 和 ConcurrentHashMap 面试问题
1\. [您将如何为 HashMap 设计一个好的密钥](#1)
1\. [您将如何为 HashMap 设计一个好的](#1)
2\. [HashMap 和 ConcurrentHashMap 之间的区别?](#2)
3\. [HashMap 和 Collections.synchronizedMap(HashMap)之间的区别吗?](#3)
4\. [ConcurrentHashMap 和 Collections.synchronizedMap(HashMap)之间的区别?](#4)
5\. [HashMap 和 HashTable 之间的区别?](#5)
6\. [HashTable 和 Collections.synchronized(HashMap)之间的区别?](#6)
7\. [密钥的随机/固定 hashCode()值的影响?](#7)
7\. [的随机/固定 hashCode()值的影响?](#7)
8\. [在多线程应用的非同步代码中使用 HashMap 吗?](#8)
## 1.如何为 HashMap 设计一个好的密钥
## 1.如何为 HashMap 设计一个好的
设计一个好的密钥的最基本的需求是“我们应该能够从映射中检索到价值对象而不会失败”,对吗? 否则,无论您如何构建精美的数据结构,它都将毫无用处。 要确定我们已经创建了一个好的密钥,我们必须知道“ [**HashMap 如何工作?**](https://howtodoinjava.com/java/collections/how-hashmap-works-in-java/ "How hashmap works in java") 。 我将介绍哈希表的工作原理,让您从链接的文章中阅读内容,但总而言之,它是基于哈希原理的。
设计一个好的键的最基本的需求是“我们应该能够从映射中检索到价值对象而不会失败”,对吗? 否则,无论您如何构建精美的数据结构,它都将毫无用处。 要确定我们已经创建了一个好的键,我们必须知道“ [**HashMap 如何工作?**](https://howtodoinjava.com/java/collections/how-hashmap-works-in-java/ "How hashmap works in java") 。 我将介绍哈希表的工作原理,让您从链接的文章中阅读内容,但总而言之,它是基于哈希原理的。
键的哈希码主要与 equals()方法结合使用,用于将键放入映射,然后从映射中搜索回来。 因此,如果在将键值对放入映射后,键对象的哈希码发生变化,则几乎不可能从映射取回值对象。 这是内存泄漏的情况。 为了避免这种情况,映射**键应该是不可变的**。 这些是 [**创建类**](https://howtodoinjava.com/java/basics/how-to-make-a-java-class-immutable/ "How to make a java class immutable") 不变的东西。
......@@ -78,13 +78,13 @@ ConcurrentHashMap Internal Structure
唯一将它们分开的是事实 **HashTable 是提升为集合框架的旧版**类。 它具有自己的额外功能,例如枚举器。
## 7.密钥的随机/固定 hashcode()值的影响
## 7.的随机/固定 hashcode()值的影响
两种情况(密钥的固定哈希码或密钥的随机哈希码)的影响将产生相同的结果,即“ **意外行为**”。 HashMap 中哈希码最基本的需求是确定存储桶的位置,以将键值对放置在哪里,以及必须从哪里检索它。
两种情况(键的固定哈希码或键的随机哈希码)的影响将产生相同的结果,即“ **意外行为**”。 HashMap 中哈希码最基本的需求是确定存储桶的位置,以将键值对放置在哪里,以及必须从哪里检索它。
如果键对象的哈希码每次都更改,则键值对的确切位置每次都将计算为不同。 这样,存储在 HashMap 中的一个对象将永远丢失,并且将其从映射取回的可能性极小。
出于同样的原因,建议密钥是不可变的,以便每次在同一密钥对象上请求时,它们都返回唯一且相同的哈希码。
出于同样的原因,建议键是不可变的,以便每次在同一键对象上请求时,它们都返回唯一且相同的哈希码。
## 8.在多线程应用中的非同步代码中使用 HashMap
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册