问题

我刚刚开始研究Java 8并试用lambdas我以为我会尝试重写一个我最近写的非常简单的东西。我需要将String of Map转换为Column到另一个String to Column的Map,其中新Map中的Column是第一个Map中Column的防御副本。列具有复制构造函数。我到目前为止最接近的是:

Map<String, Column> newColumnMap= new HashMap<>();
    originalColumnMap.entrySet().stream().forEach(x -> newColumnMap.put(x.getKey(), new Column(x.getValue())));

但我确信必须有一个更好的方法去做,我会感激一些建议。


#1 热门回答(145 赞)

你可以用aCollector

import java.util.*;
import java.util.stream.Collectors;

public class Defensive {

  public static void main(String[] args) {
    Map<String, Column> original = new HashMap<>();
    original.put("foo", new Column());
    original.put("bar", new Column());

    Map<String, Column> copy = original.entrySet()
        .stream()
        .collect(Collectors.toMap(Map.Entry::getKey,
                                  e -> new Column(e.getValue())));

    System.out.println(original);
    System.out.println(copy);
  }

  static class Column {
    public Column() {}
    public Column(Column c) {}
  }
}

#2 热门回答(20 赞)

Map<String, Integer> map = new HashMap<>();
map.put("test1", 1);
map.put("test2", 2);

Map<String, Integer> map2 = new HashMap<>();
map.forEach(map2::put);

System.out.println("map: " + map);
System.out.println("map2: " + map2);
// Output:
// map:  {test2=2, test1=1}
// map2: {test2=2, test1=1}

你可以使用forEach方法做你想做的事。

你在做什么是:

map.forEach(new BiConsumer<String, Integer>() {
    @Override
    public void accept(String s, Integer integer) {
        map2.put(s, integer);     
    }
});

我们可以将其简化为lambda:

map.forEach((s, integer) ->  map2.put(s, integer));

因为我们只是调用现有方法,所以我们可以使用amethod reference,它给我们:

map.forEach(map2::put);

#3 热门回答(11 赞)

没有重新插入所有条目到新 Map 的方式应该是最快的,因为HashMap.clone内部也执行rehash。

Map<String, Column> newColumnMap = originalColumnMap.clone();
newColumnMap.replaceAll((s, c) -> new Column(c));

原文链接