Je viens de commencer à regarder Java 8 et à essayer lambdas, je pensais essayer de réécrire une chose très simple que j'ai écrite récemment. Je dois transformer une carte chaîne en colonne en une autre carte en colonne où la colonne de la nouvelle carte est une copie défensive de la colonne de la première carte. La colonne a un constructeur de copie. Le plus proche que j'ai jusqu'à présent est:
Map<String, Column> newColumnMap= new HashMap<>();
originalColumnMap.entrySet().stream().forEach(x -> newColumnMap.put(x.getKey(), new Column(x.getValue())));
mais je suis sûr qu'il doit y avoir une meilleure façon de le faire et je vous serais reconnaissant de quelques conseils.
Vous pouvez utiliser un 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}
Vous pouvez utiliser la méthode forEach
pour faire ce que vous voulez.
Ce que tu fais là est:
map.forEach(new BiConsumer<String, Integer>() {
@Override
public void accept(String s, Integer integer) {
map2.put(s, integer);
}
});
Ce que nous pouvons simplifier en lambda:
map.forEach((s, integer) -> map2.put(s, integer));
Et comme nous appelons simplement une méthode existante, nous pouvons utiliser référence de la méthode , ce qui nous donne:
map.forEach(map2::put);
Le moyen le plus rapide sans réinsérer toutes les entrées dans la nouvelle carte ce ne sera pas le cas, car HashMap.clone
exécute également le réhachage en interne.
Map<String, Column> newColumnMap = originalColumnMap.clone();
newColumnMap.replaceAll((s, c) -> new Column(c));
Keep it Simple et utilisez 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())
);
Voici une autre façon de vous donner accès à la clé et à la valeur en même temps, au cas où vous auriez à effectuer une transformation.
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));
Si vous utilisez Guava (v11 minimum) dans votre projet, vous pouvez utiliser Maps :: transformValues .
Map<String, Column> newColumnMap = Maps.transformValues(
originalColumnMap,
Column::new // equivalent to: x -> new Column(x)
)
Si vous ne craignez pas d'utiliser des bibliothèques tierces, my cyclops-react lib possède des extensions pour tous les types JDK Collection , y compris Map . Vous pouvez directement utiliser les méthodes map ou bimap pour transformer votre map. Un MapX peut être construit à partir d'une carte existante, par exemple.
MapX<String, Column> y = MapX.fromMap(orgColumnMap)
.map(c->new Column(c.getValue());
Si vous souhaitez également changer la clé, vous pouvez écrire
MapX<String, Column> y = MapX.fromMap(orgColumnMap)
.bimap(this::newKey,c->new Column(c.getValue());
bimap peut être utilisé pour transformer les clés et les valeurs en même temps.
Au fur et à mesure que MapX s'étend, la carte générée peut également être définie comme suit:
Map<String, Column> y