我有一个包含多个键值列表的类。每个键(在列表中)应该是唯一的,所以我使用HashMap。当代码中的某个地方我向列表添加一个新项目时,我使用的是HashMap的put(K, V)
。如果尝试添加具有已存在密钥的项目,我希望我的代码抛出异常。并且,因为这样的添加是在程序的许多地方执行的,所以我想避免在每个地方添加检查。所以应该是列表类本身不允许替换现有的键值对。
我想过用我自己的HashMap类扩展它,它会执行这样的检查并抛出异常。但是,HashMap的put
不会抛出异常,所以我也不能这样做。
实现这种行为的好方法是什么?我准备好用更好的东西替换HashMap,但我需要它在添加和检索项目时都要快。
更新 谢谢大家提出的许多好建议。由于我是一个完整的Java新手,我现在需要学到很多才能选择最好的一个:)无论如何,我很感激在午餐休息时间有这么多的选择!
答案 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)
抛出IllegalArgumentException ,如果指定键或值的某些属性阻止它存储在此地图中
我认为您的用例属于该类别,因此我会使用这种可能性。由于它是一个未经检查的异常,您可以使用合成,包裹HashMap
并在IllegalArgumentException
方法的重复项上抛出put
。
答案 4 :(得分:0)
您可以抛出一个扩展RuntimeException的异常。
答案 5 :(得分:0)
您可以扩展HashMap并抛出一个Exception,它是RuntimeException的子类或put方法已抛出的Exception之一。