Besoin de convertir for loop (Java 6) en foreach (Java 8)
custFormAttrLiteList.forEach((customFormAttributeLite)-> custNameAndType = new HashMap<Long,Long>(); custNameAndType.put(customFormAttributeLite.getId(), customFormAttributeLite.getFieldType()); customNameId.put(customFormAttributeLite.getName(), custNameAndType); );
J'essaye quelque chose comme ça .. Mais je ne sais pas comment faire ça
List<CustomFormAttributeLite> custFormAttrLiteList = ArrayList ... ; Map<String,Map<Long,Long>> customNameId = new HashMap<String, Map<Long,Long>>(); Map<Long,Long> custNameAndType = null; for(CustomFormAttributeLite customFormAttributeLite:custFormAttrLiteList) { custNameAndType = new HashMap<Long,Long>(); custNameAndType.put(customFormAttributeLite.getId(), customFormAttributeLite.getFieldType()); customNameId.put(customFormAttributeLite.getName(), custNameAndType); }
3 Réponses :
Vous ne pouvez utiliser que les variables finales à l'intérieur de chaque expression lambda. Alors essayez comme ceci:
final Map<String,Map<Long,Long>> customNameId = new HashMap<String, Map<Long,Long>>(); custFormAttrLiteList.forEach((customFormAttributeLite)-> { Map<Long,Long> custNameAndType = new HashMap<Long,Long>(); custNameAndType.put(customFormAttributeLite.getId(), customFormAttributeLite.getFieldType()); customNameId.put(customFormAttributeLite.getName(), custNameAndType); });
+1, j'ajouterais qu'il n'est pas nécessaire de les marquer explicitement comme final
, juste qu'ils soient effectivement finaux, ce qui signifie que le lambda ne peut pas attribuer une nouvelle valeur à la variable.
Oui c'est bien maintenant
Vous pouvez également utiliser Collectors # groupingBy
à cette fin. Commencez par grouper par le champ de nom, puis groupez par id et type de champ.
{bar={125=126}, foo={124=125}}
Si les noms ne sont pas uniques, le résultat ne sera pas le même que vous attendez donc dans ce cas nous devons utiliser Collectors.toMap
et utilisez la mergeFunction
pour ne conserver que le deuxième non-unique entrée:
CustomFormAttributeLite c1 = new CustomFormAttributeLite("foo", 123L, 123L); CustomFormAttributeLite c2 = new CustomFormAttributeLite("foo", 124L, 125L); CustomFormAttributeLite c3 = new CustomFormAttributeLite("bar", 125L, 126L); CustomFormAttributeLite c4 = new CustomFormAttributeLite("bar", 125L, 126L);
Pour tester, j'ai utilisé l'ensemble de données suivant, pour tester ces deux solutions:
Map<String,Map<Long,Long>> customNameIdNonUnique = custFormAttrLiteList.stream() .collect(Collectors.toMap(CustomFormAttributeLite::getName, //key mapper function (obj) -> {Map<Long,Long> map = new HashMap<>(); map.put(obj.getId(), obj.getFieldType()); return map;}, //value mapper function (key1, key2)-> key2)); //retaining only the second entry
Le la deuxième solution a donné le résultat:
List<CustomFormAttributeLite> custFormAttrLiteList = new ArrayList<>(); Map<String,Map<Long,Long>> customNameId = custFormAttrLiteList.stream() .collect(Collectors.groupingBy(CustomFormAttributeLite::getName, Collectors.toMap(CustomFormAttributeLite::getId, CustomFormAttributeLite::getFieldType)));
Vous pouvez également utiliser obj -> Collections.singletonMap (obj.getId (), obj.getFieldType ())
comme fonction de mappage de valeurs.
Je vous recommande vivement d'éviter la mutation de l'état d'une collection dans forEach
. Collectez les données en utilisant plutôt .collect (...)
.
Commencez par créer une méthode ( statique ou dynamique ) pour mapper un CustomFormAttributeLite
à Map
:
Map<String, Map<Long, Long>> customNameId = custFormAttrLiteList.stream() .collect(toMap(CustomFormAttributeLite::getName,this::mapToNameAndType));
Ensuite, vous pouvez simplement collecter les données dans un nouveau Carte
en utilisant Collectors.toMap()
:
Map<Long,Long> mapToNameAndType(CustomFormAttributeLite attribute){ Map<Long, Long> map = new HashMap<>(); map.put(attribute.getId(), attribute.getFieldType()); return map; }
list.forEach
! = list.stream (). forEach
, rien de mal à muter en utilisant le premier, ce que fait l'OP.
Ce sont des lambdas avec lesquels vous travaillez, c'est ce que vous devriez rechercher, vous avez à peu près le droit pour chaque.
Doit utiliser
groupingBy
idéalement.