将对象作为参数传递并在方法中进行修改

时间:2012-06-12 10:02:52

标签: java optimization memory

假设我有一个Map<String, String>,我想要删除包含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 个答案:

答案 0 :(得分:4)

最好的方法是methodThatRemoves,因为:

  1. 就内存消耗而言:它不会创建新的映射,因此不会增加内存开销。
  2. 就CPU使用而言:迭代器具有O(1)复杂性,用于调用next或删除当前元素。

答案 1 :(得分:2)

最有效的方式 methodThatRemoves ,因为它

  • 几乎没有记忆
  • 除(轻量级)迭代器
  • 外不创建任何对象
  • 非常快(不使用任何地图查找)

我不会先复制,除非你有一个不可修改的地图,或者你需要保留原文。

答案 2 :(得分:1)

对我而言,最好的是Iterator - methodThatRemoves ,因为您没有创建中间地图而不使用put方法。

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

答案 3 :(得分:0)

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

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

如果你真的想要更深入,你应该使用分析器或某种类型来评估它。