使用Java 8 foreach转换arraylist循环

时间:2019-02-01 05:47:49

标签: java arraylist java-8

需要将for循环(Java 6)转换为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);
}

我正在尝试类似的方法。.但不确定如何做到这一点

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

                customNameId.put(customFormAttributeLite.getName(), custNameAndType);
            );

3 个答案:

答案 0 :(得分:1)

对于每个lambda表达式,您只能使用最终变量。所以尝试这样:

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 :(得分:1)

您也可以为此使用Collectors#groupingBy。首先按名称字段分组,然后按id和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)));

如果名称不是唯一的,结果将与您期望的不同,因此在这种情况下,我们需要使用Collectors.toMap并使用mergeFunction仅保留第二个非唯一的条目:

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 

作为测试,我使用了以下数据集来测试这两种解决方案:

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

第二个解决方案产生了输出:

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

答案 2 :(得分:0)

我强烈建议您避免在forEach中更改集合的突变状态。而是使用.collect(...)收集数据。

首先创建一个方法(静态动态)以将CustomFormAttributeLite映射到Map<Long,Long>

Map<Long,Long> mapToNameAndType(CustomFormAttributeLite attribute){
    Map<Long, Long> map = new HashMap<>();
    map.put(attribute.getId(), attribute.getFieldType());
    return map;
}

然后,您可以使用Map简单地将数据收集到新的Collectors.toMap()中:

Map<String, Map<Long, Long>> customNameId = 
    custFormAttrLiteList.stream()                                                                         
                        .collect(toMap(CustomFormAttributeLite::getName,this::mapToNameAndType));