在 Java8中,如何使用 lambda 将 Map < K,V > 转换为另一个 Map < K,V > ?

我刚开始研究 Java8,为了尝试 lambdas,我想尝试重写我最近写的一个非常简单的东西。我需要将一个 Map of String to Column 转换成另一个 Map of String to Column,其中新 Map 中的 Column 是第一个 Map 中 Column 的防御性副本。纵队有个复制建构子。目前为止最接近的是:

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

但我相信肯定有更好的办法我很感激你的建议。

179264 次浏览
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));

因为我们只是调用一个现有的方法,所以我们可以使用 方法参考,它给我们:

map.forEach(map2::put);

不重新插入所有条目到新映射中的方法应该是最快的 ,因为 HashMap.clone内部也执行 rehash。

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

你可以使用 收藏家:

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) {}
}
}

如果你不介意使用第三方库,我的 剑水蚤-反应库对所有的 JDK Collection类型都有扩展,包括 地图。您可以直接使用 Map 或 bimap 方法来转换 Map。一个 MapX 可以从一个现有的地图例如。

  MapX<String, Column> y = MapX.fromMap(orgColumnMap)
.map(c->new Column(c.getValue());

如果您还希望更改键,可以编写

  MapX<String, Column> y = MapX.fromMap(orgColumnMap)
.bimap(this::newKey,c->new Column(c.getValue());

Bimap 可以用来同时转换键和值。

随着 MapX 扩展 Map,生成的 Map 也可以定义为

  Map<String, Column> y

这里还有另一种方法,可以让您同时访问键和值,以防您需要进行某种转换。

Map<String, Integer> pointsByName = new HashMap<>();
Map<String, Integer> maxPointsByName = new HashMap<>();


Map<String, Double> gradesByName = pointsByName.entrySet().stream()
.map(entry -> new AbstractMap.SimpleImmutableEntry<>(
entry.getKey(), ((double) entry.getValue() /
maxPointsByName.get(entry.getKey())) * 100d))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

保持简单并使用 Java8:-

 Map<String, AccountGroupMappingModel> mapAccountGroup=CustomerDAO.getAccountGroupMapping();
Map<String, AccountGroupMappingModel> mapH2ToBydAccountGroups =
mapAccountGroup.entrySet().stream()
.collect(Collectors.toMap(e->e.getValue().getH2AccountGroup(),
e ->e.getValue())
);

如果在项目中使用番石榴(v11最小) ,则可以使用

Map<String, Column> newColumnMap = Maps.transformValues(
originalColumnMap,
Column::new // equivalent to: x -> new Column(x)
)

注意: 这个映射的值是延迟计算的。如果转换的开销很大,您可以将结果复制到一个新的 map,就像 Guava 文档中建议的那样。

To avoid lazy evaluation when the returned map doesn't need to be a view, copy the returned map into a new map of your choosing.