具有唯一性检查的HashMap

时间:2012-11-23 10:48:38

标签: java exception hashmap

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

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

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

更新 谢谢大家提出的许多好建议。由于我是一个完整的Java新手,我现在需要学到很多才能选择最好的一个:)无论如何,我很感激在午餐休息时间有这么多的选择!

6 个答案:

答案 0 :(得分:8)

您可以使用Commons Collections,例如:

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

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

当然,您可以通过构建自己的Predicate实例并使用它而不是PredicateUtils.uniquePredicate()来自定义此行为。您自己的Predicate可以执行您需要执行的任何操作,例如,它可能会抛出与默认uniquePredicate()抛出的异常类型不同的异常类型。

答案 1 :(得分:7)

我不会扩展HashMap类,因为在这种情况下,它会导致违反Liskov Substitution Principle ,因为你改变了基类方法的行为。

相反,我会使用构图:

创建实施CustomHashMap界面并拥有Map字段的HashMap类。 并重新声明HashMap类中的每个方法,为每个方法添加一个委托给HashMap方法=>如果put()已经存在,则抛出异常。

答案 2 :(得分:2)

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

答案 3 :(得分:1)

javadoc for Map#put states

  

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

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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