简体   繁体   English

使用流收集到Map

[英]Using streams to collect to Map

I have the following TreeMap : 我有以下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<>);

The key is of the form 1L (a Long ), and value of the form "7-1.50" (a String concatenation of an int and a double separated by a - ). 键的形式为1L (一个Long ),形式为"7-1.50" (一个int和一个doubleString串联,由-分隔)。

I need to create a new TreeMap where the keys are obtained by taking the int part of the values of the original Map (for example, for the value "7-1.50" , the new key will be 7 ). 我需要创建一个新的TreeMap ,其中通过获取原始Map的值的int部分来获得键(例如,对于值"7-1.50" ,新键将是7 )。 The value of the new Map would be a TreeSet containing all the keys of the original Map matching the new key. Map的值将是一个TreeSet其中包含与新键匹配的原始Map所有键。

So, for the input above, the value for the 7 key will be the Set {1L,2L,3L}. 因此,对于上面的输入, 7键的值将是Set {1L,2L,3L}。

I can do this without Stream s, but I would like to do it with Stream s. 我可以在没有Stream的情况下做到这一点,但我想用Stream做。 Any help is appreciated. 任何帮助表示赞赏。 Thank you. 谢谢。

Here's one way to do it: 这是一种方法:

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

I modified the original code to support integers of multiple digits, since it appears you want that. 我修改了原始代码以支持多个数字的整数,因为看起来你想要它。

This produces the Map : 这会产生Map

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

If you don't care about the ordering of the resulting Map and Set s, you can let the JDK decide on the implementations, which would somewhat simplify the code: 如果您不关心生成的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())));

You may try this out, 你可以尝试一下,

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

UPDATE UPDATE

If you want to split the value based on "-" since there may be more that one digit, you can change it like so: 如果你想根据“ - ”分割值,因为可能有更多的那个数字,你可以改变它:

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

Other solution would be like this 其他解决方案就是这样

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

and second step: 第二步:

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

or in one step: 或者一步到位:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM