【发布时间】:2021-10-07 17:01:32
【问题描述】:
我正在通过this 的问题将HashTable<K,V> 创建为final。我读了this 的答案,我们使用Collections.unmodifiableMap 在哈希表上放置一个不可修改的包装器。这让我想知道是否有 HashMap 实现或任何其他类似的结构,我可以随时插入,但是一旦我插入了一个键和值,就不允许在同一个键上再次插入。
例如:
private final HashMap<Integer, Integer> test = new HashMap<>();
test.put(1, 100);
test.put(2, 200);
/*
* Other insertions
*/
test.put(1, 50); //This should not be allowed
我能想到的一个解决方案是:
if(test.get(1) == null) {
test.put(1, 50); //Similarly for all insertions
}
或创建一个将执行此检查的方法,例如:
private void putIfNotPresent(int key, int value) {
if(test.get(key) == null) { //Considering that null will be returned if there is no mapping available for the key
test.put(key, value);
} else {
throw new UnsupportedOperationException;
}
}
我也知道 putIfAbsent(K, V) 方法,但如果有人尝试 put() 为已经存在的密钥设置某个值,这也不会禁止。
如果密钥已经存在,我提出的所有解决方案都不会阻止某人插入 HashMap,除非他们对每次插入都使用 putIfNotPresent() 自定义方法或 putIfAbsent 方法。是否有这样的HashMap 实现可用,一旦插入键和值,就不允许在同一个键上插入,即一旦插入带有值的键,它的行为就好像键的值是final?
【问题讨论】:
-
(AFAIK) 不,没有。但是您可以使用这些属性编写自定义
Map类。 -
只是一个问题:为什么要抛出
UnsupportedOperationException而不是IllegalStateException?抛出IllegalStateException是合乎逻辑的,因为当映射尝试引入重复项时,使用这些参数的操作处于非法状态。 -
@OlivierGrégoire 我刚刚将该异常添加为占位符,以表明它不应该发生。抛出
IllegalStateException更合乎逻辑。感谢您的意见! -
@Hulk 是不是和默认的
HashMap的putIfAbsent方法不一样,只是动作是原子执行的? -
@MathewThomas 啊是的,你是对的,它也在
Map界面上。我不知何故记错了它是特定于 CHM 的。我想我错过了使用 java 8 将它添加到 Map 中(这是通过默认方法实现的)。 CHM 从 1.5 开始就有。