Использование потоков для сбора на карту - PullRequest
0 голосов
/ 30 мая 2018

У меня есть следующее 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 (a Long) и значение формы "7-1.50" (String сцеплениеint и double, разделенных -).

Мне нужно создать новый TreeMap, где ключи получены путем взятия части значений int значенийоригинал Map (например, для значения "7-1.50" новый ключ будет 7).Значением нового Map будет TreeSet, содержащее все ключи исходного Map, соответствующие новому ключу.

Таким образом, для введенного выше значения для клавиши 7 будет Set {1L, 2L, 3L}.

Я могу сделать это без Stream с, но я бы хотел сделать это с Stream с.Любая помощь приветствуется.Спасибо.

Ответы [ 3 ]

0 голосов
/ 30 мая 2018

Вы можете попробовать это,

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

ОБНОВЛЕНИЕ

Если вы хотите разделить значение на «-», так как может быть больше одногоцифра, вы можете изменить это так:

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())));
0 голосов
/ 30 мая 2018

Другое решение будет следующим:

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))))
0 голосов
/ 30 мая 2018

Вот один из способов сделать это:

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]}

Если вам не нужно упорядочивать результирующие Map и Set s, вы можете позволить 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())));
...