gpt4 book ai didi

java - 仪表化哈希集和重写 add 和 addAll

转载 作者:行者123 更新时间:2023-11-30 02:18:15 25 4
gpt4 key购买 nike

在《Effective Java》第 2 版第 16 项中,作者提供了一个场景来说明“继承破坏封装”,其中 InstrumentedHashSet继承自HashSet并覆盖这两个方法 add()addAll() 。我的问题是为什么以下替代方案不能永远解决我们的问题?可能会出现什么样的新问题:

public class InstrumentedHashSet<E> extends HashSet<E> {

// The number of attempted element insertions
private int addCount = 0;

public InstrumentedHashSet() {
}

public InstrumentedHashSet(int initCap, float loadFactor) {
super(initCap, loadFactor);
}

@Override public boolean add(E e) {
addCount++;
return super.add(e);
}
/* only the add method has been overrided
@Override public boolean addAll(Collection<? extends E> c) {
addCount += c.size();
return super.addAll(c);
}
*/

public int getAddCount() {
return addCount;
}
}

最佳答案

如果您删除 addAll 的覆盖,你的InstrumentedHashSet将容易受到 addAll 实现变化的影响在HashSet<T> .

目前,JDK implementation leaves the implementation up to its AbstractCollection base class ,忠实地调用 add对于每个项目:

public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
Iterator<? extends E> e = c.iterator();
while (e.hasNext()) {
if (add(e.next())) // <<== This will call your override
modified = true;
}
return modified;
}

但是,也可以采用替代方法:例如 addAll可以尝试通过在addAll内部立即扩展散列桶数组来优化插入方法,而不是调用 add反复。这会破坏代码,因为 addCount将不再得到适当的维护。

[from the comment] What would incite the Java language designers in Oracle to change HashSet<T> implementation? Would not that break many java programs designed with the pre-knowledge that addAll calls add within its implementation?

这正是第 16 条试图说明的要点。一旦其他人开始从您的类继承,您就会“锁定”程序代码中未明确说明的实现方面,例如需要 addAll 的方面。调用add在每个项目上。实际上,在没有您明确确认的情况下,继承会通过“卡住”代码的各个方面来破坏封装。

关于java - 仪表化哈希集和重写 add 和 addAll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47641306/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com