CSV lesen und summieren in JAVA?

3 Antworten

Vom Fragesteller als hilfreich ausgezeichnet
Aber das ist SOOOOO umständlich, in Python mache ich das in 5 Zeilen 

Wenn ich mich in Python nicht auskenne, brauche ich dafür auch mehr als 5 Zeilen.

Ein einfaches Schema für deine Aufgabenstellung wäre:

try (var lines = Files.lines(Path.of("bla.csv"))) {
    var sum = lines.map(s -> s.split(",")[1])
            .mapToInt(Integer::parseInt)
            .sum();
    System.out.println(sum);
}

Das ist ein bisschen naiv (jede Zeile muss dem Format entsprechen, keine eingebetteten Kommas in anderen Spalten), aber du fragtest ja nach einem Grundgerüst, nicht nach einem vollständigen Programm das mit allen Eventualitäten zurechtkommt.

Für komplexeres CSV würde ich dann zu einer separaten Library raten, etwa FastCSV.

Weil du sagst, du kannst kein Python installieren: Ist es ein Muss, dass es in Java ist, oder kann es z.B. auch in Excel oder PowerShell sein? Die beiden können ganz gut mit CSVs umgehen und sind normalerweise auf jedem Bürorechner drauf.

marlisha 
Fragesteller
 02.08.2022, 15:23

Soll später auf einem Server laufen unter Linux und die Fa. hat schon viel Javazeug und will nicht 10 andere Sprachen (versteh ich aber Java ist für mich...)

Auf meinem PC hab ich Windows und Java.

0

Guckst du einfach mal hier:

https://techvidvan.com/tutorials/read-csv-file-in-java/

Dort werden dir diverse Wege aufgezeigt und entsprechende Codesnippets dazu geliefert.

schnfz  02.08.2022, 14:50

Die Beispiele dort illustrieren eher, worüber sich der FS beklagt: alles so umständlich - weil die Autoren es offenbar selber nicht besser wissen. Leider gibt's einige Websites dieser Art die zwar toll im SEO sind (tauchen immer vorn bei Websuchen auf) aber inhaltlich miserabel.

1
GuteAntwort2021  02.08.2022, 22:43
@schnfz

Ich habe mir die Beispiele nicht angeguckt, aber sie funktionieren vermutlich einwandfrei und was ich gesehen habe, waren sie für Anfänger ausgelegt.

Auch fragte er nach einem Grundgerüst, welches er einfach anpassen kann. Dieses findet er auf der gelinkten Seite.

Auch als umständlich sehe ich es nicht? Textreich, okay, aber

var sum = lines.map(s -> s.split(",")[1])
            .mapToInt(Integer::parseInt)
            .sum();

sollte wohl deutlich umständlicher zu verstehen sein, für einen Anfänger. Wenn er Python beherrscht mag er folgen können da es dort teils ähnliche Syntax/Funktionalitäten gibt, aber ich persönlich denke mir immer, man sollte erstmal das Rechnen lernen, bevor man auf einen Taschenrechner zurückgreift.

Entsprechend verstehe ich deine Kritik nicht!

0
schnfz  02.08.2022, 23:10
@GuteAntwort2021
Ich habe mir die Beispiele nicht angeguckt

Ich schon, geht ja schnell. Sie sind sinnlos umständlich, aber auch qualitativ schlecht und sollten daher von niemandem - egal ob Anfänger oder Fortgeschrittener - als Beispiel verwendet werden. Etwa hier:

try {
      File file = new File(csvFile);
      FileReader fr = new FileReader(file);
      BufferedReader br = new BufferedReader(fr);

Ganze drei Zeilen (und Variablen), nur um einen BufferedReader für ein File zu bekommen - und das nichtmal unter Verwendung von try-with-resources. Schlimmer: kein Encoding angegeben, somit ist undefiniert ob UTF-8 oder ISO-8859-1 oder gar Windows-1252 oder sonstwas verwendet wird. Klassischer Fehler, der sich oft erst später rächt, wenn der Code nicht mehr auf der eigenen Maschine laufen soll.

Die Files-Klasse, die es seit Java 7 und somit mehr als 10 Jahren gibt, ist dem Autor offenbar unbekannt. Damit wäre das ein Einzeiler und hätte klar definiertes Verhalten.

      String line = " ";
      String[] tempArr;
      while ((line = br.readLine()) != null) {

Warum wird line außerhalb der Schleife nicht nur deklariert, sondern mit " " initialisiert? Völlig sinnlos. Ebenso das "tempArr" (was für ein hilfreicher Variablenname).

      br.close();

Wie gesagt, wenn man try-with-resources kennen würde, würde die Zeile wegfallen und das Programm trotzdem robuster, weil close() auch bei Exceptions zuverlässig aufgerufen wird...aber OK, das gibt's ja erst seit einem Jahrzehnt.

    catch(IOException ioe) {
      ioe.printStackTrace();
    }

Für derartig dummes "Exceptionhandling" fliegt man in jedem technischen Interview aus dem Bewerbungsprozess. Da hat jemand Exceptions nicht verstanden, wollte aber die lästigen Compilermeldungen loswerden.

1
GuteAntwort2021  03.08.2022, 00:50
@schnfz
Ganze drei Zeilen (und Variablen), nur um einen BufferedReader für ein File zu bekommen

Ja, aber jeder kann direkt folgen. Und seit wann spielen die Anzahl der Zeilen eine Rolle? Ich sehe nicht den Vorteil in

BufferedReader br = new BufferedReader(new FileReader(new File(csvFile)));

statt

File file = new File(csvFile);
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);

auch wenn es nur eine Zeile ist. Besonders bei Anfängern... :)

Die Files-Klasse, die es seit Java 7 und somit mehr als 10 Jahren gibt, ist dem Autor offenbar unbekannt.

Oder das Tutorial stammt von vor 10+ Jahren. :)

Aber mir latte, die Diskussion führt zu nichts. Der Link hat ihm ein Grundgerüst geliefert - wie gefragt.

0
GuteAntwort2021  03.08.2022, 00:58
@schnfz
Warum wird line außerhalb der Schleife nicht nur deklariert, sondern mit " " initialisiert? Völlig sinnlos.

Aber nicht falsch und wenn ich mich recht entsinne, gab es besonders in Java früher häufiger Fehler, die auf eine fehlende Initialisierung zurückzuführen waren. Mag sein, dass es heute nicht mehr so ist - ich mache praktisch nichts mehr mit Java, aber schaden tut es auch nicht! :)

Ebenso das "tempArr" (was für ein hilfreicher Variablenname).

Ich benenne meine Variablen auch häufiger mal mit temp irgendwas. Für jeden ersichtlich, dass es einfach nur ein Zwischenspeicher ist, der kurzfristig für die Bearbeitung "gebraucht" bzw. gewünscht wird, aber keine weitreichende Rolle im Programm spielt und bald vom Garbage-Collector wieder eingesammelt wird.

Du bist kein Songwriter, du musst bei den Variablennamen keine besondere Kreativität an den Tag legen. :)

0