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% 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:
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):
Ausgabe:
%Vor% 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.
Tags und Links java java-8 pivot java-stream collectors