使用流收集到Map

时间:2018-05-30 06:57:31

标签: java java-8 java-stream

我有以下TreeMap

TreeMap<Long,String> gasType = new TreeMap<>(); // Long, "Integer-Double"
gasType.put(1L, "7-1.50");
gasType.put(2L, "7-1.50");
gasType.put(3L, "7-3.00");
gasType.put(4L, "8-5.00");
gasType.put(5L, "8-7.00");
Map<Integer,TreeSet<Long>> capacities = new TreeMap<>);

密钥的格式为1L(一个Long),格式"7-1.50"的值Stringint的连接double-分隔的TreeMap

我需要创建一个新的int,其中通过获取原始Map的{​​{1}}部分来获取密钥(例如,值"7-1.50" },新密钥将为7)。新Map的值为TreeSet,其中包含与新密钥匹配的原始Map的所有密钥。

因此,对于上面的输入,7键的值将是Set {1L,2L,3L}。

我可以在没有Stream的情况下执行此操作,但我希望使用Stream s来执行此操作。任何帮助表示赞赏。谢谢。

3 个答案:

答案 0 :(得分:4)

这是一种方法:

Map<Integer,TreeSet<Long>> capacities = 
  gasType.entrySet()
         .stream ()
         .collect(Collectors.groupingBy (e -> Integer.parseInt(e.getValue().substring(0,e.getValue ().indexOf("-"))),
                                         TreeMap::new,
                                         Collectors.mapping (Map.Entry::getKey,
                                                             Collectors.toCollection(TreeSet::new))));

我修改了原始代码以支持多位数的整数,因为看起来你想要它。

这会产生Map

{7=[1, 2, 3], 8=[4, 5]}

如果您不关心生成的MapSet的排序,您可以让JDK决定实现,这会稍微简化代码:

Map<Integer,Set<Long>> capacities = 
  gasType.entrySet()
         .stream ()
         .collect(Collectors.groupingBy (e -> Integer.parseInt(e.getValue().substring(0,e.getValue ().indexOf("-"))),
                                         Collectors.mapping (Map.Entry::getKey,
                                                             Collectors.toSet())));

答案 1 :(得分:3)

你可以尝试一下,

final Map<Integer, Set<Long>> map = gasType.entrySet().stream()
        .collect(Collectors.groupingBy(entry -> Integer.parseInt(entry.getValue().substring(0, 1)),
                Collectors.mapping(Map.Entry::getKey, Collectors.toSet())));

<强>更新

如果你想根据&#34; - &#34;分割价值。因为可能有一个以上的数字,你可以改变它:

final Map<Integer, Set<Long>> map = gasType.entrySet().stream()
        .collect(Collectors.groupingBy(entry -> Integer.parseInt(entry.getValue().split("-")[0]),
                Collectors.mapping(Map.Entry::getKey, Collectors.toSet())));

答案 2 :(得分:2)

其他解决方案就是这样

list = gasType.entrySet()
            .stream()
            .map(m -> new AbstractMap.SimpleImmutableEntry<Integer, Long>(Integer.valueOf(m.getValue().split("-")[0]), m.getKey()))
             .collect(Collectors.toList());

和第二步:

list.stream()
    .collect(Collectors.groupingBy(Map.Entry::getKey,
    Collectors.mapping(Map.Entry::getValue,Collectors.toCollection(TreeSet::new))));

或一步到位:

gasType.entrySet()
            .stream()
            .map(m -> new AbstractMap.SimpleImmutableEntry<>(Integer.valueOf(m.getValue().split("-")[0]), m.getKey()))
            .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(Map.Entry::getValue, Collectors.toCollection(TreeSet::new))))