5

我有一个包含几个键值列表的类。每个键(在列表中)都应该是唯一的,所以我使用 HashMap。当我在代码中的某个地方向列表中添加一个新项目时,我使用的是 HashMap 的put(K, V). 如果尝试添加具有现有密钥的项目,我希望我的代码抛出异常。而且,因为在程序中的许多地方都执行了这样的添加,所以我想避免在每个地方添加检查。所以应该是列表类本身不允许替换现有的键值对。

我想用我自己的扩展 HashMap 类,它会执行这样的检查并抛出异常。但是,HashMapput不会抛出异常,所以我也不能这样做。

实现这种行为的好方法是什么?我准备用更好的东西替换 HashMap,但我需要它在添加和检索项目时都快。

更新: 感谢大家的许多好建议。由于我是 Java 的完全新手,我现在需要学习很多东西才能选择最好的:) 无论如何,我很感激能在午休时间获得这么多的选择!

4

6 回答 6

8

您可以为此使用Commons Collections,例如:

Map map = MapUtils.predicatedMap(new HashMap(), PredicateUtils.uniquePredicate(),
             null);

这将创建一个Map实例,当您尝试在相同的键已经存在时插入键值对时,该实例将引发异常。

当然,您可以通过构建自己的Predicate实例并使用它而不是PredicateUtils.uniquePredicate(). 您自己的Predicate可以做任何您需要它做的事情,例如,它可能会抛出与 default 抛出的异常类型不同的异常uniquePredicate()

于 2012-11-23T10:52:28.827 回答
7

我不会扩展HashMap类,因为在这种情况下,它会导致违反里氏替换原则,因为你改变了基类方法的行为。

相反,我会使用组合:

创建您的CustomHashMap类实现Map接口并拥有一个HashMap字段。并重新声明HashMap类中存在的每个方法,为每个方法添加一个委托到原始方法HashMap,除了方法 => 如果已经存在put()则抛出异常。entry

于 2012-11-23T10:53:35.007 回答
2

几个想法:
A. 在扩展 HashMap 的类中抛出一个扩展 RuntimeException 的异常。
B. 提供某种 MapWrapper,它将接收 Map 作为参数,具有 get、put 和其他一些方法,以及更适合您的签名。

于 2012-11-23T10:51:28.940 回答
1

Map#put的javadoc 状态

如果指定键或值的某些属性阻止它存储在此映射中,则抛出 IllegalArgumentException

我认为您的用例属于该类别,因此我会使用这种可能性。由于它是一个未经检查的异常,您可以在方法中使用组合、包装 a 并在重复项上HashMap抛出一个。IllegalArgumentExceptionput

于 2012-11-23T11:06:14.973 回答
0

您可以抛出一个扩展 RuntimeException 的异常。

于 2012-11-23T10:51:15.970 回答
0

您可以扩展 HashMap 并抛出一个异常,它是 RuntimeException 的子类或 put 方法已经抛出的异常之一。

于 2012-11-23T10:58:47.717 回答