Set 接口如何强制执行无重复添加和不保留插入顺序规定

Q.1) 正如AbstractSet的文档中所写——“此类不会覆盖该类的任何实现AbstractCollection。” 如果它不覆盖更改 add(Object o)或由类实现的任何其他Collection接口协定AbstractCollection,而只是继承它们等HashSet

How doHashSet和 other Setobjects 然后强制执行诸如不重复添加检查或插入元素的 Hashtable 方式等规定,List这与or other objects 可以添加元素的方式完全不同Collection

Q.2)在文档中,对于AbstractSet,它是写的,只是添加了和 的AbstractSet实现。但是,在方法细节部分,提到了类已经覆盖了方法。是否只继承而不对这两个方法做任何改变?如果是这样,类的重要性是什么?请澄清equalshashcodeObjectequalshashcodeAbstractSetAbstractSet


手掌心
浏览 109回答 2
2回答

隔江千里

Q1:HashSet 是如何强制重复检查的?如果您查看java.util.HashSet中的实现,您将看到以下代码:-private static final Object PRESENT = new Object();public boolean add(E e) {&nbsp; &nbsp; return map.put(e, PRESENT)==null;}发生的事情相当简单;我们使用一个私有的 HashMap 实例,它接受我们提供的值并将其作为 HashMap 的键插入。映射的PRESENT值从未实际使用或检索过,但它允许我们使用此支持映射来验证该项目是否存在于集合中。如果地图中不存在我们提供的值,则调用map.put()会将项目放置在地图中并返回我们的对象。否则,地图保持不变并且该方法返回 null。HashMap 在这里为 HashSet 做着艰苦的工作。这与AbstractCollection类提供的实现不同,因此需要重写。Q2:AbstractSet对equals() & hashCode()的使用我认为您稍微误解了 AbstractSet 在这里做什么。AbstractSet 的目的是提供 equals 和 hashCode 的集合安全实现。相等检查是通过验证我们正在比较两个 Set 对象,它们具有相同的大小,并且它们包含相同的项目来执行的。public boolean equals(Object o) {&nbsp; &nbsp; if (o == this)&nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; if (!(o instanceof Set))&nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; Collection<?> c = (Collection<?>) o;&nbsp; &nbsp; if (c.size() != size())&nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; return containsAll(c);&nbsp; &nbsp; } catch (ClassCastException unused)&nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; } catch (NullPointerException unused) {&nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; }}hashCode 是通过遍历 Set 实例并迭代地散列每个项目产生的:public int hashCode() {&nbsp; &nbsp; int h = 0;&nbsp; &nbsp; Iterator<E> i = iterator();&nbsp; &nbsp; while (i.hasNext()) {&nbsp; &nbsp; &nbsp; &nbsp; E obj = i.next();&nbsp; &nbsp; &nbsp; &nbsp; if (obj != null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; h += obj.hashCode();&nbsp; &nbsp; }&nbsp; &nbsp; return h;}任何从 AbstractSet 扩展的类都将使用 equals() 和 hashCode() 的这个实现,除非它明确地覆盖它们。此实现优先于java.lang.Object中定义的默认 equals 和 hashCode 方法。

梦里花落0921

您提供的文档是针对 Java 7 的,我正在检查 Java 8 的代码,我发现了以下内容,所以我认为它与 Java 7 不一样,您仍然可以在文档时使用相同的方法检查代码对你来说不是很清楚: Q1: HashSet Overrides the add method in AbstractCollection 你可以很容易地检查这一点,如果你在某个IDE中打开HashSet代码。如果父母不重写某些方法并不意味着它的孩子不能这样做。Q2:再次通过检查代码,我们注意到 AbstractSet 定义了它自己的 equals 和 hashCode 方法的实现。它还覆盖了 AbstractCollection 的 removeAll 方法。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java