2016-10-04 2 views
1

У меня есть карта в следующем виде:Сокращение карты с помощью Java 8 Стрим API

Map<Integer, Map<String,Double>> START 

Пусть ВНУТРЕННИЙ быть внутренняя карта, т.е.

Map<String,Double> 

Например, я хотел бы уменьшить START карту в новой

Map<Integer, Double> END 

, которые имеют одинаковые ключи, но разные значения. В частности, для каждой клавиши я хочу, чтобы новое значение Double было SUM значений на карте INNER для соответствующего ключа.

Как я могу достичь этого, используя API-интерфейс JAVA 8 STREAM?

Спасибо всем.

EDIT: карта образец

------------------------------ 
|  | 2016-10-02 3.45 | 
| ID1 | 2016-10-03 1.23 | 
|  | 2016-10-04 0.98 | 
------------------------------ 
|  | 2016-10-02 1.00 | 
| ID2 | 2016-10-03 2.00 | 
|  | 2016-10-04 3.00 | 
------------------------------ 

е Я хотел бы новую карту, как следующий:

-------------------------------- 
|  |      | 
| ID1 | SUM(3.45,1.23,0.98) | 
|  |      | 
-------------------------------- 
|  |      | 
| ID2 | SUM(1.00,2.00,3.00) | 
|  |      | 
-------------------------------- 
+1

Почему ключ вашей внутренней карты представляет собой строку? Можете ли вы предоставить примерную карту? –

+0

Я бы хотел использовать API STREAM, потому что я новичок, и мне нужно понять его лучше. – Fab

+0

Что вы пробовали? Покажите нам свой код. – talex

ответ

3

Это будет работать для вас

Map<Integer, Double> collect = START.entrySet() 
     .stream() 
     .collect(
      Collectors.toMap(
       Map.Entry::getKey, 
       e -> e.getValue() 
         .values() 
         .stream() 
         .reduce(0d, (a, b) -> a + b) 
       ) 
     ); 
+1

http://stackoverflow.com/a/39851906/463758 Другой ответ сохраняет один поиск путем потоковой передачи 'entrySet()' вместо 'keySet()'. – balki

5

Это должно быть хорошим примером:

public class Main { 

    public static void main(final String[] args) { 
     final Map<Integer, Map<String, Double>> tmp = new HashMap<>(); 
     tmp.put(1, new HashMap<String, Double>() {{ 
      put("1", 3.45); 
      put("2", 1.23); 
      put("3", 0.98); 
     }}); 
     tmp.put(2, new HashMap<String, Double>() {{ 
      put("1", 1.00); 
      put("2", 2.00); 
      put("3", 3.00); 
     }}); 

     System.out.println(tmp.entrySet().stream() 
       .collect(
        toMap(Map.Entry::getKey, 
        data -> 
         data.getValue() 
          .values().stream() 
          .mapToDouble(Number::doubleValue).sum()))); 
    } 

} 

вывод будет {1=5.66, 2=6.0}, и все это делает принимает набор карт, получает его поток и собирает новые суммы карт внутренних значения карты.

+0

. Ваш код дает мне следующую ошибку: Метод toMap (Map.Entry :: getKey, ( данных) -> {}) не определен для типа Start – Fab

+0

' Проблема Collectors.toMap'. – Fab

Смежные вопросы