通过使用 stream() 压缩另一个映射来构建新的 HashMap

Construct new HashMap by compressing the other map with stream()

我需要使用 stream()

{100: [100], 101: [101], 200:[200], 201:[201]} 获取新的 HashMap<Integer, Set<Integer>>,即 {10: [100,101], 20:[200,201]}

我尝试了下面的代码,但当然行不通。

HashMap<Integer, Set<Integer>> map1 = new HashMap<>();
map1.put(100, new HashSet(Arrays.asList(100));
...
HashMap<Integer, Set<Integer>> map2 = map1.entrySet().stream().collect(
    Collectors.toMap(entry -> ((Entry<Integer, Set<Integer>>) entry).getKey()/10,
                     entry -> ((Entry<Integer, Set<Integer>>) entry).getValue()));

这会引发 java.lang.IllegalStateException: Duplicate key

你应该试试 Collectors.groupingBy :

map2 = map1.entrySet()
           .stream()
           .collect (Collectors.groupingBy (
                         entry -> entry.getKey()/10,
                         Collectors.mapping(entry -> entry.getValue(),Collectors.toSet()));

我不确定输入地图的类型是什么。如果是 HashMap<Integer,Integer>,我的代码应该可以正常工作。如果它是 HashMap<Integer, Set<Integer>>,其中 Set<Integer> 只包含一个整数(如您的示例所示),您可以将 entry.getValue() 更改为 entry.getValue().iterator().next() 以获得该整数。

map2 = map1.entrySet()
           .stream()
           .collect (Collectors.groupingBy (
                         entry -> entry.getKey()/10,
                         Collectors.mapping(entry -> entry.getValue().iterator().next(),Collectors.toSet()));

想一想,如果您的输入 Map 始终为每个键包含一个值,该值是一个集合,其中单个整数等于该键,您可以忽略该值:

map2 = map1.entrySet()
           .stream()
           .collect (Collectors.groupingBy (
                         entry -> entry.getKey()/10,
                         Collectors.mapping(entry -> entry.getKey(),Collectors.toSet()));

您可以在没有流的情况下执行此操作:

Map<Integer, Set<Integer>> map2 = new HashMap<>();
map1.forEach((i, s) -> map2.computeIfAbsent(i / 10, ii -> new HashSet<>()).addAll(s));

如果您仍然想使用一个流,即使您的集合有多个值,这仍然有效:

Map<Integer, Set<Integer>> map3 = map1.entrySet().stream()
        .collect(Collectors.groupingBy(e -> e.getKey() / 10, HashMap::new,
                Collector.of(HashSet::new, (s, e) -> s.addAll(e.getValue()), 
                        (a, b) -> {a.addAll(b); return a;}, 
                        Collector.Characteristics.UNORDERED)));

这些都假定 map1 不包含空键或任何空值。