使用Java,我有一个Map接口,它有一些项目。我想清除它中的所有数据再次使用它。哪种方法更有效?
params.clear()
或
params = new HashMap();
答案 0 :(得分:3)
我更希望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
对象可以更改,现在两个线程可以同时在{{1}内因为它们不会锁定同一个对象。为了实现线程安全,我们要么必须完全外部同步(synchronized
也没用),或者我们可以简单地使它.synchronizedMap
并使用final
。
Map.clear()
void clear() {
// atomic via synchronizedMap
map.clear();
}
(或任何final Map
)
final
或创建新逻辑的额外逻辑。您可能必须编写的用于更改地图的代码开销可能非常多。null
答案 1 :(得分:1)
一般情况下:
如果你不知道如何实现clear()
,你就无法猜测哪一个会更高效。我可以提出合成用例,其中一个或另一个肯定会赢。
如果您的地图没有数百万或数百万或记录,您可以采取任何一种方式。表现会一样。
具体做法是: 通过擦除内部数组的内容来清除HashMap。立即为GC提供旧的地图内容。当您创建新的Hashmap时,它还可以为GC + HashMap对象本身提供旧的地图内容。您正在交换几个CPU周期,因为内存略少于GC
您需要考虑其他问题:
clear()
以便其他代码看到您的更改,反之亦然