Java-Pivot-Tabelle mit Streams implementieren

8

Ich habe seit einigen Tagen mit diesem Problem gekämpft. Ich versuche, Pivot-Funktionalität mit Java-Streams zu erstellen. Ich muss nur implementieren SUMME, ZÄHLUNG, MAX, MIN und DURCHSCHNITT. Für die Eingabe habe ich einen Pivot-Spaltenindex, ein Array von Pivot-Zeilenindizes und den zu berechnenden Wert.

Der Catch ist, dass die Daten in einer List & lt; Liste & lt; Objekt & gt; & gt ;, wobei Objekt entweder String, Integer oder Double ist. aber ich werde es erst zur Laufzeit wissen. Und ich muss meine Ergebnisse als List & lt; Liste & lt; Objekt & gt; & gt;.

Ich habe Probleme mit MAX / MIN (ich gehe davon aus, dass AVERAGE MAX und MIN ähnlich ist)

Um auf mehrere Tabellenwerte zu schwenken, habe ich eine Klasse für die Verwendung meiner zweiten Gruppierung erstelltBy

Dies wird nicht kompiliert, ich bin mir nicht sicher, was ich vergleichen soll, wo ich das Objekt in int umwandeln soll oder ob ich es überhaupt tun muss. Ich möchte das alles mit einem Stream machen, aber ich bin mir nicht sicher, ob es möglich ist. Was mache ich falsch oder könnte ich es anders machen? Vielen Dank im Voraus.

%Vor%     
John H 14.09.2015, 01:52
quelle

2 Antworten

3

Da alle möglichen Werte ( String , Integer , Double ) bekanntermaßen Comparable sind, können Sie eine unkontrollierte Umwandlung in die Comparable -Schnittstelle durchführen. Vergessen Sie auch nicht das optionale zu entpacken. Schließlich, wenn ich es richtig verstehe, sollte das Ergebnis Map<Object, Map<Object, Object>> myList , nicht Map<Object, Map<Object, Integer>> myList sein, da Ihre Spalte nicht ganzzahlige Werte haben kann:

%Vor%

Ergebnisse:

%Vor%

Wie Sie sehen, können Sie sowohl die Spalten Integer als auch Double behandeln. Sogar String kann gehandhabt werden (lexikographisch wird der maximale Wert ausgewählt).

Für die Mittelwertbildung können Sie davon ausgehen, dass Ihre Spaltenwerte Zahlen sind ( Number class, entweder Integer oder Double ) und in Double sammeln (der Durchschnitt von ganzen Zahlen kann auch nicht ganzzahlig sein):

%Vor%

Ausgabe:

%Vor%     
Tagir Valeev 14.09.2015, 02:27
quelle
0

Bei der Eingabe handelt es sich um List der Zeilen, wobei jede Zeile ein List der Spalten und die Spalte String , Integer oder Double ist und nicht weiß, welche und wie viele Spalten gruppiert werden sollen indem ich nicht weiß, welche Art von Spalte aggregiert werden soll, würde ich vorschlagen, einen eigenen Aggregator zu implementieren.

Vermutlich haben alle Zeilen die gleiche Anzahl von Spalten, und alle Werte einer bestimmten Spalte haben immer den gleichen Typ (oder null ).

Was Sie wollen, ist im Grunde eine Java-Implementierung einer SQL-Anweisung group-by:

%Vor%

Sie benötigen 3 Klassen. Die erste ist die Klasse GroupBy , die equals() und hashCode() als kombinierten equals / hashcode der Gruppe nach Spalten implementieren muss: Column1, Column2, ...

Die zweite Klasse ist Aggregator , das sind zwei Klassen, die eine gemeinsame Schnittstelle implementieren, eine Klasse für die Aggregation von Integer und eine weitere für die Aggregation von Double . Der Aggregator erhält einen Wert ( Object ) und akkumuliert die Summe / Min / Max / Zählerwerte.

Die dritte Klasse ist die Hauptklasse, was Sie die Klasse Pivot nennen. Es sollte über die gewünschten Gruppierungsspalten (mit Typ) und die gewünschten Aggregationsspalten (mit Typ) angegeben werden, vorzugsweise unter Verwendung eines Builder-Musters . Er kann dann die Daten erhalten und diese Daten in einem HashMap<GroupBy, Aggregator> sammeln und dann dieses Ergebnis zurück in das für den Rückgabewert benötigte Format konvertieren.

Beispiel zum Aufrufen der Pivot-Klasse:

%Vor%

Oder wenn Sie nicht immer alle Aggregationen möchten, könnte es sein:

%Vor%

Damit kann die Implementierung von Pivot eine beliebige Anzahl von Gruppen nach Spalten und aggregierten Spalten verarbeiten, und ihre Verwendung ist sehr intuitiv.

    
Andreas 14.09.2015 02:40
quelle