10

假设我有 aMap<String, String>并且我想删除 value 包含的所有条目foo。就优化/内存/等而言,最好的方法是什么?下面四个syso打印的结果是一样的,也就是说{n2=bar}.

public static void main(String[] args) {

    Map<String, String> in = new HashMap<String, String>();
    in.put("n1", "foo");
    in.put("n2", "bar");
    in.put("n3", "foobar");

    // 1- create a new object with the returned Map
    Map<String, String> in1 = new HashMap<String, String>(in);
    Map<String, String> out1 = methodThatReturns(in1);
    System.out.println(out1);

    // 2- overwrite the initial Map with the returned one 
    Map<String, String> in2 = new HashMap<String, String>(in);
    in2 = methodThatReturns(in2);
    System.out.println(in2);

    // 3- use the clear/putAll methods
    Map<String, String> in3 = new HashMap<String, String>(in);
    methodThatClearsAndReadds(in3);
    System.out.println(in3);

    // 4- use an iterator to remove elements
    Map<String, String> in4 = new HashMap<String, String>(in);
    methodThatRemoves(in4);
    System.out.println(in4);

}

public static Map<String, String> methodThatReturns(Map<String, String> in) {
    Map<String, String> out = new HashMap<String, String>();
    for(Entry<String, String> entry : in.entrySet()) {
        if(!entry.getValue().contains("foo")) {
            out.put(entry.getKey(), entry.getValue());
        }
    }
    return out;
}

public static void methodThatClearsAndReadds(Map<String, String> in) {
    Map<String, String> out = new HashMap<String, String>();
    for(Entry<String, String> entry : in.entrySet()) {
        if(!entry.getValue().contains("foo")) {
            out.put(entry.getKey(), entry.getValue());
        }
    }
    in.clear();
    in.putAll(out);
}

public static void methodThatRemoves(Map<String, String> in) {
    for(Iterator<Entry<String, String>> it = in.entrySet().iterator(); it.hasNext();) {
        if(it.next().getValue().contains("foo")) {
            it.remove();
        }
    }
}
4

4 回答 4

4

最好的方法是methodThatRemoves因为:

  1. 在内存消耗方面:它不会创建新地图,因此不会增加内存开销。
  2. 在 CPU 使用方面:迭代器在调用下一个或删除当前元素时具有 O(1) 复杂度。
于 2012-06-12T10:13:15.457 回答
2

最有效的方法methodThatRemoves,因为它

  • 几乎不使用内存
  • 除了(轻量级)迭代器之外不创建任何对象
  • 非常快(不使用任何地图查找)

不过我不会先复制,除非您有不可修改的地图或需要保留原件。

于 2012-06-12T10:23:22.050 回答
1

对我来说最好的是带有 -methodThatRemoves 的那个Iterator因为您不创建中间 Map 并且不使用put方法。

顺便说一下,第一个:methodThatReturns可以更快,因为put复杂性是 O(1),而在最坏的情况下 remove 是 O(n),但它会使用更多内存,因为你有 2 个不同的 Map 实例。

于 2012-06-12T10:16:21.757 回答
0

我个人会同意,methodThatRemoves因为您只是执行循环操作并检查“foo”是否相等。其他人这样做以及对象映射创建和映射清除/放置操作。所以你显然有一种方法做得更少。

此外,如果您想减少内存使用量,最好不要创建额外的 HashMap 来删除 1 个或多个条目。这是假设您不介意迭代地图的额外计算。

如果你真的想更深入,你应该使用探查器或某种工具来评估它。

于 2012-06-12T10:12:22.333 回答