From 473d7200a1ae6607296697ffedf833162eac8fc8 Mon Sep 17 00:00:00 2001 From: wulnm Date: Mon, 19 Jul 2021 13:25:02 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0HashSet=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=85=83=E7=B4=A0=E6=96=B9=E6=B3=95=E7=9A=84=E6=8F=8F=E8=BF=B0?= =?UTF-8?q?&typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Java集合框架常见面试题.md | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/java/collection/Java集合框架常见面试题.md b/docs/java/collection/Java集合框架常见面试题.md index 2db5c4b1..5c0c5b38 100644 --- a/docs/java/collection/Java集合框架常见面试题.md +++ b/docs/java/collection/Java集合框架常见面试题.md @@ -432,10 +432,31 @@ TreeMap treeMap = new TreeMap<>((person1, person2) -> { ### 1.4.4. HashSet 如何检查重复 -以下内容摘自我的 Java 启蒙书《Head fist java》第二版: +以下内容摘自我的 Java 启蒙书《Head first java》第二版: 当你把对象加入`HashSet`时,`HashSet` 会先计算对象的`hashcode`值来判断对象加入的位置,同时也会与其他加入的对象的 `hashcode` 值作比较,如果没有相符的 `hashcode`,`HashSet` 会假设对象没有重复出现。但是如果发现有相同 `hashcode` 值的对象,这时会调用`equals()`方法来检查 `hashcode` 相等的对象是否真的相同。如果两者相同,`HashSet` 就不会让加入操作成功。 +在openjdk8中,`HashSet`的`add()`方法只是简单的调用了`HashMap`的`put()`方法,并且判断了一下返回值以确保是否有重复元素。直接看一下`HashSet`中的源码: +```java +// Returns: true if this set did not already contain the specified element +// 返回值:当set中没有包含add的元素时返回真 +public boolean add(E e) { + return map.put(e, PRESENT)==null; +} +``` + +而在`HashMap`的`putVal()`方法中也能看到如下说明: +```java +// Returns : previous value, or null if none +// 返回值:如果插入位置没有元素返回null,否则返回上一个元素 +final V putVal(int hash, K key, V value, boolean onlyIfAbsent, + boolean evict) { +... +} +``` + +也就是说,在openjdk8中,实际上无论`HashSet`中是否已经存在了某元素,`HashSet`都会直接插入,只是会在`add()`方法的返回值处告诉我们插入前是否存在相同元素。 + **`hashCode()`与 `equals()` 的相关规定:** 1. 如果两个对象相等,则 `hashcode` 一定也是相同的