2016-08-09 9 views
0

Ich habe eine Liste von Objekten mit Klasse wie folgt:Wie erzeuge ich zusammenfassenden Bericht mit verschachtelten Sammlung mit Java 8 Streams?

class TestResult{ 
    int userId; 
    Set<String> subjects; 
    int score; 
} 

Ich möchte in jedem Fach

Map<String,Map<Integer, Integer>> 

Die äußeree Karte hat als zentrales Thema eine Zusammenfassung der Partitur für jeden userId zu produzieren. Die innere Karte hat userId als Schlüssel, Summe der Punkte als Wert.

+1

Nizza. Was hast du bisher versucht? – Flown

+0

Der Klassenname wurde hinzugefügt. –

Antwort

0

(Bitte beachten Sie: Im Folgenden ich auf Ihre (derzeit unbenannt) Klasse als MixedScores refere)

Lassen Sie uns ein sumScores eine Methode definieren, die eine Collection<MixedScores> nimmt und gibt ein Map<String, Map<Integer, Integer>> zusammengesetzt, wie Sie gefragt.

Sie könnten eine lokale Klasse SingleScore verwenden, um eine einzelne MixedScores Instanz in mehreren Instanzen aufzuteilen, sie dann nach Thema, nach userId zu gruppieren und schließlich alle gefundenen Ergebnisse zu summieren.

In Code:

Map<String, Map<Integer, Integer>> sumScores(Collection<MixedScores> scores) { 
    class SingleScore { 
     int userId; 
     String subject; 
     int score; 

     SingleScore(MixedScores mixedScores, String subject) { 
      this.userId = mixedScores.userId; 
      this.subject = subject; 
      this.score = mixedScores.score; 
     } 

     String getSubject() { 
      return subject; 
     } 

     int getUserId() { 
      return userId; 
     } 

     int getScore() { 
      return score; 
     } 
    } 

    return scores.stream() 
      .flatMap(x -> x.subjects.stream().map(subject -> new SingleScore(x, subject))) 
      .collect(groupingBy(SingleScore::getSubject, 
        groupingBy(SingleScore::getUserId, summingInt(SingleScore::getScore)))); 
} 

Natürlich gibt es einige Importe:

import static java.util.stream.Collectors.groupingBy; 
import static java.util.stream.Collectors.summingInt; 

import java.util.Collection; 
import java.util.Map; 
import java.util.Set; 

diese Arbeit für Sie?

+0

Warum liefern Sie ohne jede Anstrengung von TO eine vollwertige Lösung? – Flown

+0

Ich sehe Ihren Punkt, @Flown; ach, ich habe deinen Kommentar zu OP * nach der Beantwortung der Frage gesehen, die mir einfach schien, aber zugegebenermaßen wenig oder keine Forschungsarbeit gezeigt hat, wie du bemerkt hast. Vielleicht hätte ich früher nachsehen müssen http://meta.stackoverflow.com/questions/261592/how-much-research-effort-is-sected-of-stack-overflow-users. Entschuldigung – logtwo

+0

Schön. Aber müssen wir eine lokale Klasse erstellen? –

0

Eine andere Möglichkeit, ohne eine neue Klasse zu schaffen, vorgeschlagen von @Flown

   scores.stream() 
        .flatMap(x -> x.subjects.stream() 
          .map(subject -> new AbstractMap.SimpleEntry<String, Entry<Integer, Integer>>(subject, 
            new AbstractMap.SimpleEntry<Integer, Integer>(x.userId, x.score)))) 
        .collect(Collectors.groupingBy(Entry<String, Entry<Integer, Integer>>::getKey, 
          Collectors.groupingBy(p -> p.getValue().getKey(), 
            Collectors.summingInt((p -> p.getValue().getValue())))));