有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用流式API转换映射列表中的值

我有一个带有非区分键的地图列表,并且喜欢使用流式API修改每个地图值。结果应该是一个新的列表,原来的列表必须保持不变

示例数据:

// [ {jpg=firstImage.jpg, png=firstImage.png}, {jpg=secondImage.jpg, png=secondImage.png} ]
Map<String, String> map1 = new HashMap<>();
map1.put("jpg", "firstImage.jpg");
map1.put("png", "firstImage.png");
Map<String, String> map2 = new HashMap<>();
map2.put("jpg", "secondImage.jpg");
map2.put("png", "secondImage.png");
List<Map<String, String>> list = new ArrayList<>();
list.add(map1);
list.add(map2);

假设我想将文件名转换为大写。凭借独特的价值观,我可以做到以下几点:

Map<String, String> copy = list.stream()
                .flatMap(e -> e.entrySet().stream())
                .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().toUpperCase()));

但是flatMap在键不明显时不起作用,它会破坏我的List<Map<String, String>>结构。我知道结构不好,但我不能改变它

预期成果:

// [ {jpg=FIRSTIMAGE.JPG, png=FIRSTIMAGE.PNG}, {jpg=SECONDIMAGE.JPG, png=SECONDIMAGE.PNG} ]

我希望通过流式API实现这一点,并尽可能避免嵌套循环


共 (2) 个答案

  1. # 1 楼答案

    这里有一个选择

        list.forEach(map -> map.replaceAll((t, f) -> f.toUpperCase()));
    

    我正在修改您列表中的现有地图。而且它没有使用流

    编辑:感谢VGR的极大简化

    编辑:因为您需要保持原始结构不变,Eugene’s solution就可以了。您也可以在副本上应用replaceAll()。一个例子:

        List<Map<String, String>> result = new ArrayList<>(list);
        list.replaceAll(m -> {
                    Map<String, String> newMap = new HashMap<>(m);
                    newMap.replaceAll((t, f) -> f.toUpperCase());
                    return newMap;
                });
    

    或者是一种不同的方法,这种方法有一个流:

        List<Map<String, String>> result = list.stream()
                .map(m -> {
                    Map<String, String> newMap = new HashMap<>(m);
                    newMap.replaceAll((t, f) -> f.toUpperCase());
                    return newMap;
                })
                .collect(Collectors.toList());
    

    我想说,我更喜欢哪一种,主要是口味的问题

  2. # 2 楼答案

    您不能使用flatMap,因为这样会将所有条目合并到一个流中,从而失去将它们取回的可能性

    您需要从List转换每个单独的元素,例如:

      List<Map<String, String>> result = list.stream()
                .map(map -> map.entrySet().stream()
                              .collect(Collectors.toMap(
                                      Map.Entry::getKey, 
                                      e -> e.getValue().toUpperCase())))
                .collect(Collectors.toList());
    
        System.out.println(result);
        // [{jpg=FIRSTIMAGE.JPG, png=FIRSTIMAGE.PNG}, {jpg=SECONDIMAGE.JPG, png=SECONDIMAGE.PNG}]