【问题标题】:Exporting afterNodeAccess from HashMap从 HashMap 导出 afterNodeAccess
【发布时间】:2014-12-07 12:31:38
【问题描述】:

在我的程序中,我有一个扩展 HashMap 的类。我想在对 HashMap 节点进行任何修改后执行一些方法。看起来 HashMap 有一些有趣的方法:

void afterNodeAccess(Node<K,V> p) { }
void afterNodeInsertion(boolean evict) { }
void afterNodeRemoval(Node<K,V> p) { }

但不幸的是,它们都是包保护的,我不能在我的课堂上覆盖它们。当然有解决方法 - 我可以将我的班级转移到 java.util 包,但在我看来这不是一个好的做法。那么有没有更清洁的方法来实现这一点?


编辑:我删除了以前的课程,因为它没有任何意义。请参阅答案下的 cmets。

【问题讨论】:

  • 重写调用afterNodeInsetion和co的方法怎么样?
  • 正如我所说,这些方法是包保护的。我已经制作了 HashMapModInterface 类来解决它,但我认为它不够干净。

标签: java hashmap java-8


【解决方案1】:

将您的类声明为其他提供程序包的成员真的是个好主意吗?
我的意思是不是。只有当我需要更改系统行为时,我才会这样做。
如果您要覆盖上面提到的 3 个方法,它们是 LinkedHashMap 的回调,您无法保证这些方法在下一个 Java 版本中仍然存在

编辑
来自 cmets 的考虑总结

使用委托而不是扩展 Hashmap
如果您实现 Map 接口(不扩展 HashMap,仅使用内部 HashMap 对象进行委托),当您更改 java 版本时,如果接口发生更改,编译器会自动通知您。如果你扩展 HashMap 并覆盖受保护的方法,你就失去了这个优势。每次更新 Java,即使是次要版本,您都必须检查源代码是否有修改。也许这会花费您比现在预期更多的时间。

但是(感谢 Holger 的建议),例如map.keySet().remove(x) 可能会在不调用地图上的公共修改方法的情况下从地图中删除条目。与使用迭代器删除项目类似。

因此,仅编写 HashMap 的委托不会让您在每次修改后都添加代码。但是您覆盖包保护方法的第一个想法也是不可能的,因为(还有 Holger 的注释)它们甚至可能在同一版本的 Java 中消失或更改其签名,因为它们不是任何合同的一部分。而java.util 是一个被禁止的包名!

【讨论】:

  • 是的,我也是这么认为的,但是有比这 3 个更多的公共方法可以覆盖。我有什么保证,在下一个版本中不会有更多的公共修改方法。而且这3个受保护的方法更方便。
  • 这也是真的。但这只是现在更方便。如果您实现 Map 接口(不扩展 HashMap,仅使用内部 HashMap 对象进行委托),当您更改 java 版本时,如果接口发生更改,编译器会自动通知您。如果你扩展 HashMap 并覆盖受保护的方法,你就失去了这个优势。每次更新 Java,即使是次要版本,您都必须检查源代码是否有修改。也许这会花费您比现在预期更多的时间。
  • 感谢您的建议。我会考虑的。
  • @Holger:我没有写保证以后不会添加任何修改方法。也许我上面的评论更清楚了。
  • 你写了“如果你覆盖了公共修改方法,你就拥有了你所需要的一切,因为地图只会通过调用公共方法来改变”。这完全是错误的,即使不考虑未来的变化,例如map.keySet().remove(x) 可能会在不调用map 上的public 修改方法的情况下从映射中删除一个条目。与使用 Iterator 删除项目类似。并且暗示最好不要使用 cmets 中的建议并不会改变 answer 中建议的性质。
猜你喜欢
  • 1970-01-01
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-13
  • 1970-01-01
  • 2013-02-12
  • 2016-02-05
相关资源
最近更新 更多