使用java流api在map中查找重复值

7gs2gvoe  于 2021-07-05  发布在  Java
关注(0)|答案(1)|浏览(285)

我试图编写一个程序,在map中找到重复的值,这个map是使用list和utility方法创建的。
我可以使用for循环获得预期的输出,但是使用它的代码太长了。
我尝试使用如下所示的javastreamapi,但得到的结果是空的。

public class PrintListElements {
    public static void main(String[] args) {
        List<String> roles = new ArrayList<>();
        roles.add("1");
        roles.add("2");
        roles.add("3");
        roles.add("4");
        roles.add("5");
        roles.add("6");
        roles.add("7");
        roles.add("1");
        HashMap<String, List<String>> idToMap = new HashMap<>();
        roles.stream().map(role -> {
            if (idToMap.containsKey(role)) {
              return   idToMap.get(role).add(getName(role));
            } else {
                return idToMap.put(role, new ArrayList<>(Arrays.asList(getName(role))));
            }
        })

        idToMap.entrySet().forEach(e-> {
            if(e.getValue().size()>1) {
                System.out.println("found a key which has duplicate value : "+ e.getKey());
            }
        });

    }

    public static List<String> getNameLL(String id) {
        ArrayList<String> ll = new ArrayList<String>();
        ll.add(getName(id));
        return ll;
    }

    public static String getName(String id) {
        switch (id) {
            case "1":
                return "one";
            case "2":
                return "two";
            case "3":
                return "third";
            case "4":
                return "four";
            case "5":
                return "fifth";
            case "6":
                return "six";
            case "7":
                return "seven";
            case "8":
                return "one";
            default:
                return "one";
        }
    }
}

预期产量:

[one, one]
[two]
[three]
[four]
[five]
[six]
[seven]

有谁能帮我,用java流api得到上面期望的输出结果吗

laawzig2

laawzig21#

你可以用 Collectors.groupingBy 按键分组并使用 Collectors.mapping Map值并收集为每个键的列表。

Map<String, List<String>> idToMap = 
    roles.stream()
         .collect(Collectors.groupingBy(e -> e, 
                      Collectors.mapping(e -> getName(e), Collectors.toList())));

或者 map 操作是懒惰的,所以代码在里面 .map 未执行。您可以使用终端操作,如 forEach 通过重构当前代码,

roles.forEach(role -> {
    if (idToMap.containsKey(role)) {
       idToMap.get(role).add(getName(role));
    } else {
       idToMap.put(role, new ArrayList<>(Arrays.asList(getName(role))));
    }
});

可以使用 Mapmerge 方法

roles.forEach(
    role -> idToMap.merge(role, new ArrayList<>(Arrays.asList(getName(role))), (a, b) -> {
      a.addAll(b);
      return a;
    }));

更新:如果您只想打印重复值,您可以使用 Collectors.counting() 获取密钥的频率作为结果collect as Map<String, Integer> ```
roles.stream()
.collect(Collectors.groupingBy(e -> e, Collectors.counting()))
.entrySet()
.forEach(e -> {
if (e.getValue() > 1) {
System.out.println("found a key which has duplicate value : " + e.getKey());
}
});

相关问题