2017-11-30 12 views
3

List에 각각 Map이있는 클래스가 있다고 가정 해 봅니다. MapJava 8 스트림 - 맵을 병합하고 "값"의 평균을 계산합니다.

public class Test { 
    public Map<Long, Integer> map; 
} 

Long 키는 타임 스탬프이며 Integer 값 점수이다.

나는 모든 객체 및 출력 고유의 타임 스탬프합니다 ( Long들) 및 평균 점수와 Map에서지도를 결합 할 수있는 Stream을 만들려고하고 있습니다.

나는이 코드를 가지고 있지만, 그것은 나에게 모든 점수의 합 등을 제공하지 평균합니다 (Integer 클래스는 평균 방법이 없습니다).

Test test1 = new Test(); 
    test1.map = new HashMap() {{ 
     put(1000L, 1); 
     put(2000L, 2); 
     put(3000L, 3); 
    }}; 

    Test test2 = new Test(); 
    test2.map = new HashMap() {{ 
     put(1000L, 10); 
     put(2000L, 20); 
     put(3000L, 30); 
    }}; 

    List<Test> tests = new ArrayList() {{ 
     add(test1); 
     add(test2); 
    }}; 

    Map<Long, Integer> merged = tests.stream() 
      .map(test -> test.map) 
      .map(Map::entrySet) 
      .flatMap(Collection::stream) 
      .collect(
        Collectors.toMap(
          Map.Entry::getKey, 
          Map.Entry::getValue, 
          Integer::sum 

        ) 
      ); 
    System.out.println(merged); 

것은 나는이 쉬운 문제가 너무 너무 고유의 타임 스탬프와 Map 모든 점수의 List과 출력도 괜찮을 것, 하나의 Stream에 해결되지 않을 수도 있음을 생각하고 있어요. 그렇다면 평균을 계산할 수 있습니다.

Map<Long, List<Integer>> 

가능한가요? 대신 Collectors.groupingBy 사용 Collectors.toMap

답변

4

:

Map<Long, Double> merged = tests.stream() 
     .map(test -> test.map) 
     .map(Map::entrySet) 
     .flatMap(Collection::stream) 
     .collect(
       Collectors.groupingBy(
         Map.Entry::getKey, 
         Collectors.averagingInt(Map.Entry::getValue) 
       ) 
     ); 

아, 그리고 당신은 아마 더 이상 필요하지 않더라도, 당신이 얻을 수있는 Map<Long, List<Integer>> 당신은 그냥 간단하게 질문의 마지막 부분에 대한 질문 :

Map<Long, List<Integer>> merged = tests.stream() 
    .map(test -> test.map) 
    .map(Map::entrySet) 
    .flatMap(Collection::stream) 
    .collect(
      Collectors.groupingBy(
        Map.Entry::getKey, 
        Collectors.mapping(Map.Entry::getValue, Collectors.toList()) 
      ) 
    ); 
+0

고마워요. – Martin

+2

제 생각 엔 항상 메소드 참조를 사용하려고 시도 할 필요는 없습니다. .map (test :: test.map) .map (Map :: entrySet) .flatMap (Collection :: stream)보다 간단하다.'.flatMap (test -> test.map.entrySet(). stream())' ', imho – Holger

+0

@Holger 동의합니다. 나는 그것이 문제가 아니기 때문에 나는 파이프 라인의 그 부분에 집중하지 않고 그대로 유지했다는 것을 인정해야한다. – Eran