Convert arraylist loop with java 8 foreach

Er KK Chopra :

Need to convert for loop (Java 6) to foreach (Java 8)

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

I am trying something like that.. But not sure how to do that

custFormAttrLiteList.forEach((customFormAttributeLite)->
                custNameAndType = new HashMap<Long,Long>();
                custNameAndType.put(customFormAttributeLite.getId(), customFormAttributeLite.getFieldType());

                customNameId.put(customFormAttributeLite.getName(), custNameAndType);
            );
Fullstack Guy :

You can also use Collectors#groupingBy for this purpose. First group by the name field then group by id and fieldType.

List<CustomFormAttributeLite> custFormAttrLiteList = new ArrayList<>();

Map<String,Map<Long,Long>> customNameId = custFormAttrLiteList.stream()
                        .collect(Collectors.groupingBy(CustomFormAttributeLite::getName,
                         Collectors.toMap(CustomFormAttributeLite::getId, CustomFormAttributeLite::getFieldType)));

If the names are not unique, the result won't be the same as you expect so in that case we need to use Collectors.toMap and use the mergeFunction to retain only the second non-unique entry:

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 

As a test I've used the following dataset, to test both these solutions:

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);

The second solution yielded the output:

{bar={125=126}, foo={124=125}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=152781&siteId=1