2016-05-12 2 views
0

Я хотел бы преобразовать (с помощью Java 8 потока) в Map<Long, List<MyClass>> в Map<Long, Set<Long>> где Set<Long> представляет id каждый MyClass из List.Java 8 поток Map <Long, Список <MyClass>> на карту <Long, Set <Long>>

Я попытался:

myFirstMap.entrySet().stream() 
     .map(e -> e.getValue().stream() 
      .map(MyClass::getId) 
      .collect(Collectors.toSet())) 

Но я не могу понять, как получить результат.

+2

Ваша правка аннулирует ответы, здесь уже целый год. Пожалуйста, не делай этого. – shmosel

ответ

4

Вы сопоставляете экземпляры Map.Entry с номерами Set<Long>, что подразумевает отказ от отслеживания ключей исходной карты, что делает невозможным их сбор на новую карту с теми же ключами.

Первый вариант для отображения Map.Entry<Long, List<MyClass>> экземпляров в Map.Entry<Long, Set<Long>> экземпляров, а затем собирать записи на новую карту:

Map<Long, Set<Long>> result= 
    myFirstMap.entrySet().stream() 
     .map(e -> new AbstractMap.SimpleImmutableEntry<>(e.getKey(), 
       e.getValue().stream().map(MyClass::getId).collect(Collectors.toSet()))) 
     .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); 

Альтернативой является плавить шаг map и collect в один, чтобы сделать преобразование прямо в функции стоимости, представленной toMap коллектору:

Map<Long, Set<Long>> result= 
    myFirstMap.entrySet().stream().collect(Collectors.toMap(
     Map.Entry::getKey, 
     e -> e.getValue().stream().map(MyClass::getId).collect(Collectors.toSet()))); 

Таким образом, вы избежите создания новых Map.Entry экземпляров и получить однако более сжатый код, однако, обладает гибкостью, поскольку вы не можете связать дополнительные потоковые операции между ними.

0

Другим решением, без накладных расходов внешней Stream заключается в использовании Map.forEach() так:

Map<Long,Set<Long>> result = new HashMap<>(); 
myFirstMap.forEach((k,v) -> 
    result.put(k, v.stream() 
     .map(MyClass::getId) 
     .collect(Collectors.toSet()))); 

Что на самом деле просто удобный метод, чтобы сделать это:

Map<Long,Set<Long>> result = new HashMap<>(); 
for (Map.Entry<Long, List<MyClass>> entry : myFirstMap.entrySet()) { 
    result.put(entry.getKey(), entry.getValue().stream() 
     .map(MyClass::getId) 
     .collect(Collectors.toSet())); 
}