我刚刚开始研究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())));
但我确信必须有一个更好的方法来做这件事我会感激一些建议。
答案 0 :(得分:186)
您可以使用Collector:
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) {}
}
}
答案 1 :(得分:22)
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));
因为我们只是调用现有方法,所以我们可以使用method reference,这样就可以了:
map.forEach(map2::put);
答案 2 :(得分:12)
没有将所有条目重新插入到新地图中的方式应该是最快的,因为HashMap.clone
内部也会执行rehash。
Map<String, Column> newColumnMap = originalColumnMap.clone();
newColumnMap.replaceAll((s, c) -> new Column(c));
答案 3 :(得分:7)
保持简单并使用Java 8: -
Map<String, AccountGroupMappingModel> mapAccountGroup=CustomerDAO.getAccountGroupMapping();
Map<String, AccountGroupMappingModel> mapH2ToBydAccountGroups =
mapAccountGroup.entrySet().stream()
.collect(Collectors.toMap(e->e.getValue().getH2AccountGroup(),
e ->e.getValue())
);
答案 4 :(得分:2)
这是另一种让您可以同时访问密钥和值的方法,以防您必须进行某种转换。
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));
答案 5 :(得分:1)
如果您不介意使用第三方库,我的cyclops-react lib包含所有JDK Collection类型的扩展程序,包括Map。您可以直接使用map或bimap方法转换Map。 MapX可以从现有Map构建,例如。
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<String, Column> y
答案 6 :(得分:1)
如果您在项目中使用Guava(最低v11),则可以使用Maps::transformValues。
Map<String, Column> newColumnMap = Maps.transformValues(
originalColumnMap,
Column::new // equivalent to: x -> new Column(x)
)