清除Java HashMap的最有效方法

时间:2014-01-30 10:53:57

标签: java

使用Java,我有一个Map接口,它有一些项目。我想清除它中的所有数据再次使用它。哪种方法更有效?

params.clear() 

params = new HashMap();

2 个答案:

答案 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
  • “有效的Java#13:赞成不变性” - 虽然地图是可变的,但我们的参考不是。

答案 1 :(得分:1)

一般情况下: 如果你不知道如何实现clear(),你就无法猜测哪一个会更高效。我可以提出合成用例,其中一个或另一个肯定会赢。 如果您的地图没有数百万或数百万或记录,您可以采取任何一种方式。表现会一样。

具体做法是: 通过擦除内部数组的内容来清除HashMap。立即为GC提供旧的地图内容。当您创建新的Hashmap时,它还可以为GC + HashMap对象本身提供旧的地图内容。您正在交换几个CPU周期,因为内存略少于GC

您需要考虑其他问题:

  • 您是否将此引用传递给其他代码/组件?您可能希望使用clear()以便其他代码看到您的更改,反之亦然
  • 你想要没有麻烦,没有副作用的新地图吗?我会去创建一个新的。