Best Practice Problem mit (einfacher) Doppelt-Schleife

richtig

Mitglied
Hi, ich hab hier ein Problem:

Java:
  public static List<List<List<Object>>> getTodayData() throws Exception {
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    df.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
    List<List<List<Object>>> results = new ArrayList<>();
    List<List<Object>> data = MDB.get();
    data.sort(Comparator.comparingLong(a -> ((Timestamp) a.get(0)).getTime()));
    for (int k = 0; k < data.size(); k++) {
      List<List<Object>> list = new ArrayList<>();
      while (k == 0
          || k < data.size()
              && ((Timestamp) data.get(k - 1).get(0)).getTime()
                  == ((Timestamp) data.get(k).get(0)).getTime()) {
        list.add(data.get(k++));
      }

      double[] sums = new double[7];
      for (List<Object> os : list) {
        for (int i = 0; i < sums.length; i++) {
          sums[i] += (double) os.get(i + 3);
        }
      }
      list.add(
          new ArrayList<>(
              List.of(
                  list.get(0).get(0),
                  "sums",
                  "---",
                  sums[0],
                  sums[1],
                  sums[2],
                  sums[3],
                  sums[4],
                  sums[5],
                  sums[6])));
      for (List<Object> os : list) {
        os.set(0, df.format(new Date(((java.sql.Timestamp) os.get(0)).getTime())));
        for (int i = 3; i < os.size(); i++) {
          os.set(i, String.format("%.2f", (Double) os.get(i)));
        }
      }
      results.add(list);
    }
    return results;
  }

Mein Problem ist, dass ich eigentlich zwei Tabellen in einer Datenbanktabelle stehen habe, die sich nur durch den Timestamp unterscheiden. Beispiel:

123aaa
123bbb
132aaa (diese Zeile ist weg ...)
132bbb
132ccc

Durch meine Schleife wird aber die Zeile (132, a, aa) "verschluckt", und ich weiß nicht, wie ich den Tabellen-Split mit der verschachtelten Schleife eleganter formulieren kann.

Hat jemand vielleicht eine Idee?
 

richtig

Mitglied
Ach herrje, manchmal sieht man den Wald vor lauter Bäumen nicht ...

Die Idee ist, in Zeile 9 nicht nur den (aller)ersten Eintrag als ersten Eintrag zu betrachten, sondern jedes Mal, wenn sich k durch die äußere Schleife um eins erhöht:

Java:
    for (int k = 0; k < data.size(); ) {
      List<List<Object>> list = new ArrayList<>();
      boolean isFirstEntry = true;
      while (isFirstEntry
          || k < data.size()
              && ((Timestamp) data.get(k - 1).get(0)).getTime()
                  == ((Timestamp) data.get(k).get(0)).getTime()) {
        list.add(data.get(k++));
        isFirstEntry = false;
      }

Dadurch wird nichts mehr "verschluckt" ...

Sorry, aber das ist mir erst nach dem Posten dieser Frage aufgefallen. 😁
 

mihe7

Top Contributor
Mein Problem ist, dass
der Obfuscator einfach zu gut ist :p

Also, wenn ich es richtig sehe, dann hast Du Datensätze, deren erste Spalte ein Timestamp ist und die von der vierten bis zur zehnten Spalte double-Werte enthalten. Die Datensätze sollen nun nach Timestamp gruppiert werden und für jede Gruppe willst Du auch die Summen der double-Werte haben.

Zum Gruppieren gibt es in der Stream API einen Collector (s. Collectors.groupingBy). Ich würde hier allerdings auch spezielle Typen einführen.
 

richtig

Mitglied
Also, wenn ich es richtig sehe, dann hast Du Datensätze, deren erste Spalte ein Timestamp ist und die von der vierten bis zur zehnten Spalte double-Werte enthalten. Die Datensätze sollen nun nach Timestamp gruppiert werden und für jede Gruppe willst Du auch die Summen der double-Werte haben.

Ja, das hast du richtig gesehen. In der ersten Spalte steht ein Timestamp, dann folgen zwei Strings und die restlichen 7 Werte sind double-Werte.

Hier ist mal ein Beispiel (sensible Werte habe ich entfernt):

1728827891404.png

Das Problem ist also, dass innerhalb der Tabelle mehrere kleine Tabellen stehen ("Subtables"), die nur über den Timestamp gruppiert werden können. (Mein alter Datenbankprofessor hätte mir die Ohren langgezogen ...)

Ich würde hier allerdings auch spezielle Typen einführen.
Hast du dazu vielleicht eine Idee?
 

mihe7

Top Contributor
Naja, das fängt halt schon damit an, dass Du normalerweise die Einträge als Typen modellierst.
Java:
record Entry(Date time, String asset, String type, double free, double locked, double sum, 
        double usdFree, double usdLocked, double usdSum1, double usdSum2) {
    static Entry from(List<Object> row) {
        return new Entry(
                 (Date) row.get(0),
                 (String) row.get(1),
                 (String) row.get(2),               
                 (double) row.get(3),
                 (double) row.get(4),
                 (double) row.get(5),
                 (double) row.get(6),
                 (double) row.get(7),
                 (double) row.get(8),
                 (double) row.get(9));
    }
}
D. h. MDB.get() würde schon ein List<Entry> liefern, oder aber man wandelt das um:
Java:
List<List<Object>> data = MDB.get();
List<Entry> entries = data.stream().map(Entry::from).toList();
und die kann man nach time gruppieren:
Java:
Map<Date, List<Entry>> entriesByTime = entries.stream().collect(Collectors.groupingBy(Entry::time));
Für die Einträge der Map kann wieder mit ein Typ angegeben werden.
Java:
record EntriesByTime(Date time, List<Entry> entries) {}

Man könnte Entry jetzt z. B. in die Lage versetzen, zu addieren und EntriesByTime die Summe für alle Entries zu bilden. Insgesamt erhält man dann etwas wie
Java:
public class Report {
    record Entry(Date time, String asset, String type, double free, double locked, double sum,
            double usdFree, double usdLocked, double usdSum1, double usdSum2) {
        Entry(Date time) {
            this(time, "", "", 0d, 0d, 0d, 0d, 0d, 0d, 0d);
        }
        static Entry from(List<Object> row) {
            return new Entry(
                    (Date) row.get(0), (String) row.get(1), (String) row.get(2),
                    (double) row.get(3), (double) row.get(4), (double) row.get(5),
                    (double) row.get(6), (double) row.get(7), (double) row.get(8), (double) row.get(9));
        }
        Entry plus(Entry other) {
            return new Entry(time, "sum", "---",
                    free + other.free, locked + other.locked, sum + other.sum,
                    usdFree + other.usdFree, usdLocked + other.usdLocked,
                    usdSum1 + other.usdSum1, usdSum2 + other.usdSum2);
        }
    }
    record EntriesByTime(Date time, List<Entry> entries) {
        Entry getSums() {
            return entries.stream().reduce(new Entry(time), Entry::plus);
        }
    }
    List<EntriesByTime> getEntriesByTimes(List<List<Object>> data) {
        Map<Date, List<Entry>> entryMap = data.stream()
                .map(Entry::from).collect(Collectors.groupingBy(Entry::time));
        return entryMap.entrySet().stream()
                .map(mapEntry -> new EntriesByTime(mapEntry.getKey(), mapEntry.getValue()))
                .toList();                
    }
}

Damit könntest Du z. B. aufrufen: new Report().getEntriesByTimes(MDB.get()), um eine Liste von EntriesByTime-Instanzen zu erhalten. Die kannst Du anschließend formatieren. Über die Methode getSums() erhältst Du den "Summeneintrag" zu jeder "Subtabelle".

Das mal so als erste Idee. Natürlich sollten statt Entry bzw. Entries passendere Namen verwendet werden.
 

richtig

Mitglied
Habs mir durchgelesen. Ja, das wäre sinnvoller (geeignete Datenstruktur/Datentypen bei der "Datentransformation" (ich weiß nicht mehr genau, wie dieser Schritt in einer Webanwendung genau bezeichnet wird ...)).

Andererseits bin ich keiner, der zu viele unnötige Strukturen einzieht, da später die Template-Engine auch mit einem einfachen List<List<Object>> (oder auch nur ein 2D-Array) zurechtkommt.

Eine Sache fehlt bei dir aber noch:

for (List<Object> os : list) { os.set(0, df.format(new Date(((java.sql.Timestamp) os.get(0)).getTime()))); for (int i = 3; i < os.size(); i++) { os.set(i, String.format("%.2f", (Double) os.get(i))); } }

Fürs Frontend genügt es, wenn der Akteur (also ich) später lediglich zwei Nachkommastellen sieht ...
 

richtig

Mitglied
Btw., mMn, könnte HTML(5) endlich mal sortierbare (und aggregatierbare) Tabellen als Feature einführen, dann könnte man an der Stelle auch auf JS verzichten ... aber das ist nur meine Meinung.
 

Marinek

Bekanntes Mitglied
Meiner Meinung nach ist das Problem trivial und nur bedingt durch die schlechte Datenstruktur und daraus sich ergebene statische Methode komplizierter gemacht.

@mihe7 hat ja schrieben wie es besser geht.

Da bringen ja auch sortierbare HTML5 Tabellen nix.
 

richtig

Mitglied
Hab es mal weiter vereinfacht:

Java:
  public static List<List<List<Object>>> getTodayData() throws Exception {
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    df.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));

    List<List<List<Object>>> tables = new ArrayList<>();
    List<List<Object>> data = MDB.get();
    data.sort(Comparator.comparing(a -> ((java.sql.Timestamp) a.get(0))));
    for (int i = 0; i < data.size(); ) {
      List<List<Object>> table = new ArrayList<>();
      boolean isFirstEntry = true;
      while (isFirstEntry || i < data.size() && data.get(i - 1).get(0).equals(data.get(i).get(0))) {
        table.add(data.get(i++));
        isFirstEntry = false;
      }
      tables.add(table);
    }
    for (List<List<Object>> table : tables) {
      table.add(
          Stream.concat(
                  Stream.of(table.get(0).get(0), "sum", "---"),
                  IntStream.range(3, 10)
                      .mapToObj(i -> table.stream().mapToDouble(r -> (double) r.get(i)).sum()))
              .collect(Collectors.toCollection(ArrayList::new)));
    }
    for (List<List<Object>> table : tables) {
      for (List<Object> row : table) {
        row.set(0, df.format(new Date(((java.sql.Timestamp) row.get(0)).getTime())));
        IntStream.range(3, row.size())
            .forEach(i -> row.set(i, String.format("%.2f", (Double) row.get(i))));
      }
    }
    return tables;
  }

Schön wäre es, wenn man Zeile 26 bis 30 auch noch weiter vereinfachen könnte (die innere Schleife).
 

Marinek

Bekanntes Mitglied
Nee du. Sehe zero Vereinfachung. Und selbst wenn man die Zeilen irgendwie vereinfacht. Da sind so viele Fehler drin.

Warum kann man nicht mit einer Datenstruktur arbeiten wie oben skizziert??
 

KonradN

Super-Moderator
Mitarbeiter
Also ob da Fehler drin sind oder nicht, kann ich nicht sagen und ehrlich gesagt will ich das auch nicht.

Der Code ist und bleibt unleserlich. Der Hinweis von @mihe7 wurde von dir mit einem Like versehen aber den Hinweis willst Du dennoch nicht umsetzen.

Wenn Du eine vernünftige Datenstruktur aufbauen würdest, dann würdest Du auch von so static Methoden wegkommen. So Methoden würden sich mehr oder weniger von selbst unterteilen zu kleinen, lesbaren Methoden in den einzelnen Klassen. Die einzelnen Methoden wären dann auch einfach Unit-Testbar....
 

Marinek

Bekanntes Mitglied
Hm, wohl nur viel heiße Luft ...
Nö, kann ich gerne ausführen:

Während ich es geschrieben habe, dachte ich, es wäre offensichtlich, scheint aber nicht so zu sein.

Fehler 1: Keine Objektorientierten Datenstrukturen.

Das führt zu einer über komplexen Darstellung, wie man hier sehen kann.

Fehler 2: Die Daten scheinen aus einer DB zu kommen. Warum, werden die da nicht schon sortiert…

Fehler 3: Überdurchschnittlich hohe Nutzung von Magic Numbers. Wenn sich da mal ne Spalte im Select ändert, dann gute nacht.

Fehler 4: Nachdem die tables erstellt worden sind, werden alle Einträge durchlaufen und mit Strings ersetzt. Puhhh. Warum macht das nicht die GUI.

Super gravierender Fehler 1: Du lernst nicht aus deinen Fehlern.

Super gravierender Fehler 2: Du hast eine grundauf falsche Vorstellung des Berufs Informatiker.

Weiterhin viel erfolg. 🍀
 

mihe7

Top Contributor
Eine Sache fehlt bei dir aber noch:
Ja, das hatte ich auch angemerkt:
Die kannst Du anschließend formatieren.
Das habe ich absichtlich rausgelassen, weil das ein anderer Part ist.

Andererseits bin ich keiner, der zu viele unnötige Strukturen einzieht, da später die Template-Engine auch mit einem einfachen List<List<Object>> (oder auch nur ein 2D-Array) zurechtkommt.
Tatsächlich machen wir das auch, aber nur für die ausschließliche Anzeige via JSF. Es gibt eine DB-Abfrage, die "Tupel" liefert und JSF zeigt den Spaß in einer Tabelle an. Thema erledigt.

Allerdings: Du willst im Code mit den Daten arbeiten, da würde ich das nicht mehr so machen wollen. Aber wenn Du unbedingt mit Object und Listen arbeiten willst, dann solltest Du wenigstens den Code in Methoden aufteilen.
 

Barista

Top Contributor
Java:
for (int k = 0; k < data.size(); ) {
List<List<Object>> list = new ArrayList<>();
boolean isFirstEntry = true;
while (isFirstEntry
|| k < data.size()
&& ((Timestamp) data.get(k - 1).get(0)).getTime()
== ((Timestamp) data.get(k).get(0)).getTime()) {
list.add(data.get(k++));
isFirstEntry = false;
}
Dadurch wird nichts mehr "verschluckt" ...

Du kannst die boolean-Variable isFirst einsparen, indem Du eine do-while-Schleife verwendest.

do-while-Schleife gab es bei älteren Programmiersprachen als REPEAT UNTIL.

Außerhalb der Schleife das Schleifenkriterium (Gruppenkriterium) einer Variable zuweisen (final, also eigentlich nicht variabel).

Den / die Sammler-Variablen (Akku) vor der Schleife mit 0 oder so initialisieren.

In der Schleife die Daten auf die Sammler aufaddieren (bei Dir richtig).

Weiterschalten des Zeigers (Cursor), in Deinem Fall die Variable k nur in der innersten Schleife, das ist richtig.

Im while-Statement zuerst auf das Ende der Daten abfragen (bei Dir k>= data.size(), wenn es ein Iterator wäre, dann hasNext(), beim JDBC-ResultSet muss man nach meiner Erinnerung erste next aufrufen und prüft dann auf Ende, ein bisschen komisches API).

Nach der inneren Schleifen Gruppensumme und so weiter ausgeben.

Außen herum eine Schleife, die nur auf das Ende der Daten prüft.

Du könntest dieses Codegerüst einfach mal als Test aufbauen, um alle relevanten Fälle zu testen (erste Gruppe, letzte Gruppe, Gruppe mit nur einem Element, Gruppe mit mehreren Elementen, sicher gibt es noch mehr, fällt mir jetzt nicht ein).

Wenn Dir Unit-Tests nicht so vertraut sind, dann einfach in einer main-Methode hinschreiben und bei falschem Ergebnis eine Exception werfen, habe ich früher auch mal so gemacht.

Wenn das Gerüst steht, eine Kopie machen und den konkreten Kram reinbasteln.
 

richtig

Mitglied
Ja, das hatte ich auch angemerkt:

Das habe ich absichtlich rausgelassen, weil das ein anderer Part ist.


Tatsächlich machen wir das auch, aber nur für die ausschließliche Anzeige via JSF. Es gibt eine DB-Abfrage, die "Tupel" liefert und JSF zeigt den Spaß in einer Tabelle an. Thema erledigt.

Allerdings: Du willst im Code mit den Daten arbeiten, da würde ich das nicht mehr so machen wollen. Aber wenn Du unbedingt mit Object und Listen arbeiten willst, dann solltest Du wenigstens den Code in Methoden aufteilen.
Danke , das ist verständlich . Mit Marinek Kommentar kann ich wenig anfangen.
 

mihe7

Top Contributor
Man kann den Spaß auch einfach mit einer Map gruppieren, wenn man denn will:
Java:
Map<Date, List<List<Object>>> tables = new TreeMap<>();
for (List<Object> row : data) {
     tables.computeIfAbsent((Date) row.get(0), key -> new ArrayList<>()).add(row);
}
Die Sortiererei übernimmt hier die TreeMap automatisch. Dementsprechend kann man die Tabellen sortiert nach Datum ausgeben, indem man einfach über die Einträge iteriert:
Java:
for (Map.Entry<Date, List<List<Object>>> tableEntry : tables.entrySet()) {
    System.out.println("Eintraege fuer " + tableEntry.getKey());
    for (List<Object> row : tableEntry.getValue()) {
        System.out.println(row.stream().map(String::valueOf).collect(Collectors.joining(",")));
    }
}
 

richtig

Mitglied
Du machst mit Comparatoren und Streams rum, willst aber nicht verstehen, dass auch die db sortieren kann (besser soll), dass die Nutzung eines DTO Sinn ergeben könnte oder auch dass die View sich mitunter um die Konvertierung der Daten kümmern kann?

Respekt!
Ne, das nicht. Er schreibt etwas von "magischen Variablen", die schlicht nicht gegeben sind. ;) Insofern einfach eine weitere Troll-Antwort, imo.
 

Nouser

Mitglied
Ne, das nicht. Er schreibt etwas von "magischen Variablen", die schlicht nicht gegeben sind.

Java:
new double[7]
i + 3
sums[0] - sums[6]
int i = 3
Das sind keine 'magic numbers'? Damit machst du ein Refactoring unnötig schwer und jeder in deiner Firma, der den Code nach dir nochmal anfassen muss, wird dich hassen. Ein DTO kann da durchaus helfen.
 

KonradN

Super-Moderator
Mitarbeiter
Also es war die Rede von „magic numbers“:

Da findet sich aber extrem viel zu … also einfach mal Google nutzen oder einfach nur mit Clean Code auseinander setzen …

Kann man machen. Aber dabei nutzt du keine funktionale Programmierung (groupBy ...) und das sollte man auch vermeiden.
??? Es ergibt für mich keinen Sinn, funktionale Dinge an Stellen zu nutzen, an denen es andere, einfachere Lösungen gibt. KISS wäre hier ein Stichwort.

Die schreiben, dass du ein Troll bist. 🤣
Da lässt man Dich mal etwas gewähren und bannt den neuen Account nicht sofort und schon kommen solche Antworten von Tobias … willst du Dich mit sowas nicht einfach etwas zurück halten? Dann klappt es evtl. auch, dass Du nicht ständig neue Accounts erstellen musst …
 

Barista

Top Contributor
Man kann den Spaß auch einfach mit einer Map gruppieren, wenn man denn will:
Kann man machen. Aber dabei nutzt du keine funktionale Programmierung (groupBy ...) und das sollte man auch vermeiden.
Ich weiß nicht wie man Dein Problem funktional lösen kann.

Naiv würde ich sagen, in Java ist funktional das Stream-API.

Da kann man zwar gruppieren, aber ich habe keine Idee, wie man dort das Tabellen-Layout reinbastelt.

Die Map-Lösung ist insofern elegant, weil die Daten nicht vorsortiert sein müssen.

Der Code wäre dann auch ziemlich einfach/verständlich.

Ich habe so was auch mal gemacht, die Kunden waren sehr zufrieden damit.

Ich hatte vorgeschlagen, mal zu analysieren, wie der vorherige Code überhaupt funktioniert hat. Das wurde abfällig abgelehnt.

Natürlich müssen die Daten in den Speicher passen.
 

richtig

Mitglied
sums[0] - sums[6]
Ähm, das steht an keiner Stelle.

IntStream.range(3, 10)
Das ist die EINZIGE Stelle, an der "feste Werte" vorkommen, und diese Stelle wird ohnehin angefasst werden müssen, wenn sich das Datenbankmodell ändern sollte.

und jeder in deiner Firma, der den Code nach dir nochmal anfassen muss, wird dich hassen.
Sehr ausdifferenziert ... Aber, wer mich aktuell hasst (oder auch nicht hasst), ist mir eigentlich wumpe. Wir sind doch nicht im KiGa.

Btw., das ist ein privates Projekt von mir.

Da lässt man Dich mal etwas gewähren und bannt den neuen Account nicht sofort und schon kommen solche Antworten von Tobias … willst du Dich mit sowas nicht einfach etwas zurück halten?
Schon gut, ich halte nun den Rand. 😐 Danke, dass du mich etwas gewähren lassen hast.
 

KonradN

Super-Moderator
Mitarbeiter
Es geht hier doch um clean code, nicht um unnötige Dinge. ;)
Und im Rahmen von Clean Code ist eine saubere Unterteilung eben wichtig. Dass Du dies als "unnötige Dinge" bezeichnest und statt dessen mit Listen von Listen von Listen von Objects arbeitest, sagt schon recht viel aus.

Aber Du hast genügend Hinweise bekommen und Du hast beschlossen, diese zu ignorieren. Das ist Dein gutes Recht aber das führt dazu, dass wir uns dann in der Sache einig sind, dass wir dies nicht weiter vertiefen müssen (obwohl Dein Code aus meiner Sicht nur als schlechtes Beispiel dienen kann).
 

Oneixee5

Top Contributor
Mal eine andere Sache zu #4. Warum machst du das nicht in SQL? Es geht ja um Datenbanktabellen oder nicht? Ich sehe hier eine Kombination von Fenster- und Aggregatfunktionen. Es gibt vermutlich noch DB's die das nicht können, dass wäre aber eher ein Grund auf eine richtige DB zu wechseln.
 

KonradN

Super-Moderator
Mitarbeiter
Mal eine andere Sache zu #4. Warum machst du das nicht in SQL? Es geht ja um Datenbanktabellen oder nicht? Ich sehe hier eine Kombination von Fenster- und Aggregatfunktionen. Es gibt vermutlich noch DB's die das nicht können, dass wäre aber eher ein Grund auf eine richtige DB zu wechseln.
Das ist ja prinzipiell auch schon vorgeschlagen worden. Scheitert evtl. an den Kenntnissen. An einem DB Layer wie Hibernate dürfte es nicht scheitern, denn dann hätte er ja auch Datenklassen ....

Und alle Ideen wurden abgeblockt als unnötig - daher macht das wohl (leider) keinen wirklichen Sinn mehr.
 

Oneixee5

Top Contributor
Das ist ja prinzipiell auch schon vorgeschlagen worden. Scheitert evtl. an den Kenntnissen. An einem DB Layer wie Hibernate dürfte es nicht scheitern, denn dann hätte er ja auch Datenklassen ....

Und alle Ideen wurden abgeblockt als unnötig - daher macht das wohl (leider) keinen wirklichen Sinn mehr.
Ah sorry, ich habe nicht alles gelesen: TLDR; Ich habe nur so bei mir gedacht: "So einen Java-Code würde ich mir nicht antun." -> dazu fehlt mir der Masochismus. Letztendlich benötigt man JSON oder XML für die Übertragung der Daten an ein Web-Frontend. Die Umwandlung kann die DB ja auch gleich mit erledigen. So das am Ende eine Endpunkt-Java-Code von 2 bis 3 Zeilen raus kommt und eine Abfrage von etwa 20 Zeilen, wenn man sehr großzügig formatiert. Dann wären auch keine Datenklassen notwendig.
 

KonradN

Super-Moderator
Mitarbeiter
Was, ODER BY soll man nicht kennen?
Evtl. solltest Du genauer Lesen / versuchen, das Gesagte wirklich zu verstehen. Denn es ging nicht nur eine reine Sortierung. Auch Gruppierungen sind in SQL meist möglich.

Da du selbst ein ORDER BY nicht verwendest und statt dessen selbst sortierst, könnte man natürlich bewerten wollen, aber so weit wollte ich nicht gehen ...
 

KonradN

Super-Moderator
Mitarbeiter
Du hattest aber selber mal KISS, YAGNI und Overengineering erwähnt.
Wenn man SQL wirklich kennt, dann ist es eine einfache Sache und die Datenbank selbst optimiert die Query, nutzt dann auch Indices und so, so dass es letzten Endes sehr einfach ist. Daher ist es Simple / Stupid.

Wo sollte YAGNI verletzt sein? Du brauchst ja ganz offensichtlich die Sortierung / Gruppierung. Wenn Du uns hier natürlich Code vorgesetzt hast, den Du eh nicht brauchst: Worum dreht sich der Thread?

Overengineering müsstest Du auch erklären. Du brauchst Daten aus einer Datenbank und Du greifst die Daten genau so ab, wie Du diese brauchst. Also etwas, das eigentlich eine einfache Sache sein sollte.
 

richtig

Mitglied
Mein Frage, was am Grouping-Algorithmus falsch ist, hat sich doch schon geklärt.

Ich brauche jetzt keine Java EE JPA + Spring E-Commerce-Anwendung daraus machen, das gibt mein Anwendungsfall schlicht nicht her.

Nicht falsch verstehen, aber ich finde, das ufert hier langsam etwas aus. Der Nächste möchte ein rosa Einhorn. :D
 

Barista

Top Contributor
Warum machst du das nicht in SQL? Es geht ja um Datenbanktabellen oder nicht? Ich sehe hier eine Kombination von Fenster- und Aggregatfunktionen. Es gibt vermutlich noch DB's die das nicht können, dass wäre aber eher ein Grund auf eine richtige DB zu wechseln.

Ich würde das Problem lieber in Java Lösen, als in SQL. Warum sollte ich SQL lernen, wenn ich Java kann und es damit lösen kann.

Aussagen wie,: "das sollte man lieber der DB überlassen" sollten auch mit Argumenten untermauert werden, statt zu unterstellen "ist eben so".

Ich habe mal ein bißchen gelesen über SQL Window-Funktionen, ist aber nicht meine Welt.

Deshalb wüsste ich nicht, wie ein SQL-Abfrage-Ergebnis, was ja eigentlich Tabellenzeilen sind, den Unterschied zwischen Datenzeilen und Summenzeilen (je Gruppe und gesamt), sowie zwischen Datenzeilen und Kopfzeilen (benötigt man wahrscheinlich auch) codieren soll.

Das ist dann wahrscheinlich kein "reines" SQL.
 

richtig

Mitglied
Sagen wir so ... für meine Zwecke ist eine hyperkomplexe SQL-Abfrage nicht nützlich und wiederverwenden muss ich diese auch nicht. Aber rein theoretisch ginge das natürlich.
 

KonradN

Super-Moderator
Mitarbeiter
Ich würde das Problem lieber in Java Lösen, als in SQL. Warum sollte ich SQL lernen, wenn ich Java kann und es damit lösen kann.
Das ist doch unter dem Strich schon benannt worden: Wenn es an dem Wissen fehlt, dann ist das halt so. Wenn Du keine wirkliche Ahnung von SQL hast, dann lass die Finger davon. Das ändert aber nichts daran, dass man auch damit sehr viel machen kann, dass es sehr leistungsstark ist und dann deutlich performanter läuft.

sollten auch mit Argumenten untermauert werden
Und es wurde doch als Argument gebracht, dass es den Code vereinfachen würde. Und spätestens so einfache Dinge wie eine Sortierung kann die Datenbank besser, so da ein Index vorhanden ist. Dann hat die Datenbank die Sortierung bereits und man hat dann halt kein O(n*log(n)) oder so als Komplexitätsklasse.

Klar, für kleine Hello World Programme ist es egal. Aber wenn es um große Projekte geht, dann wird sowas halt tatsächlich relevant. Und dann schaut man sich evtl. bei Queries auch an, was der Query Optimizer der Datenbank so treibt.
 

richtig

Mitglied
Wenn schon sortiert, läuft die Sortierung in Java in Linearzeit. Das sollte (in meinem Fall) kein Problem darstellen. Wenn die Datenbank wächst, dann vielleicht schon.
 

Oneixee5

Top Contributor
Warum sollte ich SQL lernen,
hyperkomplexe SQL-Abfrage
Naja, das ist wohl eine Sache der Vorbildung. Zu meinen Aufgaben gehört auch reine Datenbankprogrammierung, --optimierung und -design. Man kann übrigens in verschiedenen DB's nicht nur SQL und PLSQL/MSSQL/TSQL inkl. verschiedener Dialekte programmieren, sondern auch in Java oder C. Allerdings gibt es dabei Einschränkungen, wie: keine Threads usw. Die "Ich kann eine Programmiersprache und löse damit alles."-Theorie funktioniert in der Praxis eher weniger. Ich kenne eher folgendes Paradigma: Ein Softwareentwickler sollte jedes Jahr eine neue Programmiersprache lernen. Auch wenn man die nicht unbedingt einsetzt oder bis zu Perfektion beherrscht, ist es doch nützlich mal über den Tellerrand zu schauen und mögliche neue Vorgehensmodelle oder Ansichten zu übernehmen.

Bspw. gab es in unserer Oracle früher mal ein Projekt, welches PDF aus Daten direkt in der DB erzeugt hat. Klar geht das heute besser und das Projekt ist längst abgelöst aber eine Sache muss man dabei immer im Auge behalten: Man holt für jede Aufgabe eine gewisse Menge Daten aus der DB indem man sie selektiert, über das Netzwerk zieht, in den Speicher lädt, Objekte umwandelt, darauf eine Logik anwendet und das Ergebnis wieder im Speicher hält, dann in eine Transformation anwendet, damit das Ergebnis weiterverarbeitet werden kann und schließlich das Resultat zum Nutzer überträgt und den Speicher wieder lehrt. Für das Ganze habe ich dann irgendwo einen Server im ein paar virtuellen Cores und etwas Ram.
Mach ich das direkt in der DB habe ich meistens richtig viel Power - 4x164 metal Cores. RAM, soviel dass es die Vorstellung übersteigt, Caches und Optimizer und ... Das ganze ohne Netzwerk dazwischen oder zusätzliche Programme und lahme Hardware, alles nativ compiliert und ohne das man sich selbst um die ganzen Details und den Betrieb kümmern muss - man muss zugeben, das hat was! Natürlich ist das keine Lösung für alles aber Power ist was geiles. Wenn ich irgendwo meine 200ms Response-Time nicht schaffe, dann suche ich oft in dieser Richtung nach Zeitreserven. Auch deshalb lohnt es sich SQL zu lernen. Wozu man mit SQL in der Lage ist versteht man erst, wenn man selbst mal auf die dunkle Seite der Macht wechselt.
 
Zuletzt bearbeitet:

richtig

Mitglied
... aber naja, wer nie den Blick über den Tellerrand macht, der findet Datenbank-Anfragesprachen auch für alles probat. Hat dann aber auch nichts mehr mit Informatik und so zu tun.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Problem mit Lehrzeichen und String bei einfacher Chiffre Java Basics - Anfänger-Themen 8
G Problem mit einfacher For-Schleife und Double Wert Java Basics - Anfänger-Themen 4
K Verständnis Problem bei Server/Client Java Basics - Anfänger-Themen 2
I WildFily - unterschiedliche Libs im Projekt verursachen Problem Java Basics - Anfänger-Themen 11
imocode Vererbung Problem mit Vererbung Java Basics - Anfänger-Themen 2
L Taschenrechner Problem Java Basics - Anfänger-Themen 4
I Applikationsserver (WildFly) - Zugriff auf Ressourcen.. Problem mit Pfade Java Basics - Anfänger-Themen 10
A ScheduledExecutorService problem Java Basics - Anfänger-Themen 7
marcelnedza Problem mit Weltzuweisung, JavaKarol Java Basics - Anfänger-Themen 13
XWing Methoden rückgabe Problem? Java Basics - Anfänger-Themen 6
M Erste Schritte Collatz Problem max int Java Basics - Anfänger-Themen 3
M Problem bei verschachtelter for-Schleife bei zweidimensionalen Arrays Java Basics - Anfänger-Themen 3
C GLOOP Problem beim Erstellen der Kamera Java Basics - Anfänger-Themen 9
nelsonmandela Problem bei Ausgabe einer Switch - Case Funktion Java Basics - Anfänger-Themen 5
frager2345 Problem mit Methode Java Basics - Anfänger-Themen 4
L Problem bei Rechnung mit Math.pow Java Basics - Anfänger-Themen 13
A Thread-Schreibe-Lese-Problem Java Basics - Anfänger-Themen 4
SUPERTJB return Problem Java Basics - Anfänger-Themen 3
sserio BigInteger Problem Java Basics - Anfänger-Themen 4
JordenJost Taschenrechner problem Java Basics - Anfänger-Themen 5
K Problem mit "Random" Java Basics - Anfänger-Themen 5
S Datei anlegen Problem! Groß- und Kleinschreibung wird nicht unterschieden Java Basics - Anfänger-Themen 4
sserio Problem beim Anzeigen Java Basics - Anfänger-Themen 5
xanxk Problem For-Schleife mit Charakter Java Basics - Anfänger-Themen 2
L Unbekanntes Problem mit 2d Array Java Basics - Anfänger-Themen 6
sserio Liste erstellt und ein Problem mit dem Index Java Basics - Anfänger-Themen 8
sserio Schwimmen als Spiel. Problem mit to String/ generate a card Java Basics - Anfänger-Themen 4
J Schleife Problem Java Basics - Anfänger-Themen 2
D Problem mit der Erkennung von \n Java Basics - Anfänger-Themen 2
milan123 das ist meine aufgabe ich hab das problem das bei mir Wenn ich die Richtung der Linien verändern will und drei davon sind richtig, verändere ich die 4 Java Basics - Anfänger-Themen 3
M Verständins Problem bei Aufgabe Java Basics - Anfänger-Themen 4
HeiTim Problem mit der Kommasetzung an der richtigen stelle Java Basics - Anfänger-Themen 59
Temsky34 Problem mit dem Code Java Basics - Anfänger-Themen 17
P Problem mit Calendar.getDisplayName() Java Basics - Anfänger-Themen 8
C Problem mit mehreren Methoden + Scanner Java Basics - Anfänger-Themen 5
P Datei einlesen, nach Begriff filtern und in Datei ausgeben. Problem Standardausgabe über Konsole Java Basics - Anfänger-Themen 19
M Problem mit Klassenverständnis und Button Java Basics - Anfänger-Themen 8
EchtKeineAhnungManchmal hallo habe ein Problem mit einer Datei -> (Zugriff verweigert) Java Basics - Anfänger-Themen 4
H Problem mit Verzweigungen Java Basics - Anfänger-Themen 6
H Problem mit Rückgabewert Java Basics - Anfänger-Themen 7
josfe1234 JAVA FX problem Java Basics - Anfänger-Themen 3
A Code Problem Java Basics - Anfänger-Themen 6
Henri Problem von Typen Java Basics - Anfänger-Themen 7
J Problem mit "ArrayIndexOutOfBoundsException" Java Basics - Anfänger-Themen 11
K jackson Mapping - Problem mit Zeitzonen Java Basics - Anfänger-Themen 10
B Threads Problem mit mehreren Threads Java Basics - Anfänger-Themen 38
I Output BigDecimal anstatt double / Problem beim Rechnen Java Basics - Anfänger-Themen 16
D Schleifen Problem Java Basics - Anfänger-Themen 2
H So viele Fehlermeldungen, dass ich nicht weiß wo das Problem ist. Java Basics - Anfänger-Themen 6
J JAVA-Problem blockiert MEDIATHEKVIEW Java Basics - Anfänger-Themen 13
J extends Problem Java Basics - Anfänger-Themen 2
C Polymorphie-Problem Java Basics - Anfänger-Themen 3
Kalibru Problem bei Ausgabe von Objekt Java Basics - Anfänger-Themen 1
I Format Problem mit Wert - bekomme 0,10 anstatt 10,00 Java Basics - Anfänger-Themen 6
J Problem mit einer Methode die gewissen Inhalt einer Array löschen soll Java Basics - Anfänger-Themen 9
J Problem mit einer Methode, die beliebig viele Objekte in Array speichern soll Java Basics - Anfänger-Themen 6
J Allgemeines Problem mit Klassen Java Basics - Anfänger-Themen 5
U Problem mit dem initialisieren meines Strings in einer Schleife Java Basics - Anfänger-Themen 5
amgadalghabra algorithmisches Problem Java Basics - Anfänger-Themen 19
J Traveling Salesman Problem [Arrays] Java Basics - Anfänger-Themen 9
R ArrayList Problem Java Basics - Anfänger-Themen 6
InfinityDE Problem mit Datenübergabe an Konstruktor Java Basics - Anfänger-Themen 7
C RegEx Problem Java Basics - Anfänger-Themen 4
J Anfänger TicTacToe, Problem bei Gewinnoption, sowohl Unentschieden Java Basics - Anfänger-Themen 8
E Taschenrechner GUI Problem mit Fehlerhandling Java Basics - Anfänger-Themen 6
M Input/Output Fallunterscheidung Problem Java Basics - Anfänger-Themen 17
P Problem beim Überschreiben einer vererbten Methode Java Basics - Anfänger-Themen 4
M Problem bei Ausgabe Java Basics - Anfänger-Themen 7
Splayfer Java Array Problem... Java Basics - Anfänger-Themen 2
G Problem bei der Ausgabe einer Main Claase Java Basics - Anfänger-Themen 7
F Problem mit KeyListener in kombination mit dem ActionListener Java Basics - Anfänger-Themen 4
G Subset sum problem mit Backtracking Java Basics - Anfänger-Themen 18
N Problem mit Scanner Java Basics - Anfänger-Themen 2
J Klassen Problem Java Basics - Anfänger-Themen 8
A Out.format problem. Java Basics - Anfänger-Themen 3
J Problem bei der Programmierung eines Tannenbaums Java Basics - Anfänger-Themen 9
A Array problem Java Basics - Anfänger-Themen 16
2 Taschenrechner mit GUI Problem bei der Berechnung Java Basics - Anfänger-Themen 8
W Remote Method Invocation RMI - Problem Java Basics - Anfänger-Themen 0
I Ich habe ein Problem Java Basics - Anfänger-Themen 3
A Problem bei returnen eines Wertes Java Basics - Anfänger-Themen 6
M Regex Erstellung Problem Java Basics - Anfänger-Themen 2
D Input/Output Problem bei der Benutzereingabe eines Befehls Java Basics - Anfänger-Themen 14
M (Sehr großes Problem) Listen als static in anderen Klassen verwendet Java Basics - Anfänger-Themen 12
F Habe ein problem mit dem ActionListener Java Basics - Anfänger-Themen 3
C Regex-Problem Java Basics - Anfänger-Themen 4
J Problem beim vergleich von zwei Integer Java Basics - Anfänger-Themen 3
M Problem in der Modellierung Java Basics - Anfänger-Themen 20
W Wo ist das URL-Problem ? Java Basics - Anfänger-Themen 1
S Generics-Problem: Class, Class<?>, Class<Object> Java Basics - Anfänger-Themen 4
D FileWriter / FileReader Problem Java Basics - Anfänger-Themen 10
G Problem beim Speichern von Objekten in einer Datei Java Basics - Anfänger-Themen 7
S Compiler-Fehler Exception in thread "main" java.lang.Error: Unresolved compilation problem: Java Basics - Anfänger-Themen 6
J Problem mit Array: 2 Klassen Java Basics - Anfänger-Themen 2
S Collections funktionale Listen (ListNode<E>) review und problem beim clone Java Basics - Anfänger-Themen 0
W OOP Vererbung und Problem bei Zählschleife in einer Methode Java Basics - Anfänger-Themen 10
C Problem mit If Else If und Überprüfung eines Counters Java Basics - Anfänger-Themen 3
F Problem mit Listen Java Basics - Anfänger-Themen 5
I wieder mit einer Umwandelung habe ich Problem (diesmal von char Array zu char) Java Basics - Anfänger-Themen 1
J Problem bei Umrechnung von Hex in Bin Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben