Java 8を調べ始めたばかりで、ラムダを試してみるために、最近書いた非常に簡単なものを書き直そうと思いました。 String to ColumnのMapを、新しいMapのColumnが最初のMapのColumnの防御コピーであるString to Columnの別のMapに変換する必要があります。列にはコピーコンストラクターがあります。これまでで一番近いのは:
Map<String, Column> newColumnMap= new HashMap<>();
originalColumnMap.entrySet().stream().forEach(x -> newColumnMap.put(x.getKey(), new Column(x.getValue())));
しかし、それを行うにはもっと良い方法があるに違いないと確信しており、いくつかのアドバイスに感謝します。
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) {}
}
}
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);
}
});
これをラムダに単純化できます:
map.forEach((s, integer) -> map2.put(s, integer));
そして、既存のメソッドを呼び出しているだけなので、 method reference を使用できます。
map.forEach(map2::put);
すべてのエントリを新しいマップに再挿入しない方法が最速です HashMap.clone
が内部的に再ハッシュを実行するため、そうはなりません。
Map<String, Column> newColumnMap = originalColumnMap.clone();
newColumnMap.replaceAll((s, c) -> new Column(c));
シンプルにして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())
);
プロジェクトでGuava(v11以上)を使用する場合、 Maps :: transformValues を使用できます。
Map<String, Column> newColumnMap = Maps.transformValues(
originalColumnMap,
Column::new // equivalent to: x -> new Column(x)
)
何らかの変換を行う必要がある場合に、キーと値に同時にアクセスできる別の方法を次に示します。
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));
サードパーティのライブラリを使用してもかまわない場合、my cyclops-react libには Map を含むすべての JDK Collection タイプの拡張機能があります。マップまたはbimapメソッドを直接使用して、マップを変換できます。 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<String, Column> y