我更喜欢clear(),因为您可以将Map 设为final 成员。
class Foo {
private final Map<String, String> map = new HashMap<String, String>();
void add(String string) {
map.put(string, "a value");
}
void clear() {
map.clear();
}
}
如果您每次都分配一个新的Map,您可能会遇到多线程问题。
下面是一个使用 Map 包裹在 Collections.synchronizedMap 中的几乎线程安全的示例,但它会在您每次清除它时分配一个新映射。
class MapPrinter {
private static Map<String, String> createNewMap() {
return Collections.synchronizedMap(new HashMap<String, String>());
}
private Map<String, String> map = createNewMap();
void add(String key, String value) {
// put is atomic due to synchronizedMap
map.put(key, value);
}
void printKeys() {
// to iterate, we need to synchronize on the map
synchronized (map) {
for (String key : map.values()) {
System.out.println("Key:" + key);
}
}
}
void clear() {
// hmmm.. this does not look right
synchronized(map) {
map = createNewMap();
}
}
}
clear 方法导致了一个大问题:synchonized(map) 将不再按预期工作,因为 map 对象可以更改,现在两个线程可以同时位于这些 synchronized 块中,因为它们不会锁定同一个对象。为了实现真正的线程安全,我们要么必须完全在外部同步(.synchronizedMap 将毫无用处),要么我们可以简单地将其设为final 并使用Map.clear()。
void clear() {
// atomic via synchronizedMap
map.clear();
}
final Map(或任何final)的其他优点
- 没有额外的逻辑来检查
null 或创建一个新的。更改地图可能需要编写的代码开销非常大。
- 不会意外忘记分配
Map
- “Effective Java #13: Favor Immutability” - 虽然地图是可变的,但我们的参考不是。