Input/Output CSV Parser list unvollständig

Deiuta

Mitglied
Hallo ihr,

bin neu hier und blutige Java-Anfängerin.

Trotzdem arbeite ich an einem umfangreichen Projekt und muss unter Anderem CVS-Dateien mit vielen Datensätzen einlesen können. Dazu habe ich folgenden Code gefunden und ihn nach meinen Bedürfnissen abgeändert :

Java:
package Import;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;

import javax.swing.JFileChooser;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

public class CSVParser {
   
   
    public static String fileChose() {

        JFileChooser fc = new JFileChooser();

        int ret = fc.showOpenDialog(null);

        if (ret == JFileChooser.APPROVE_OPTION) {

            File file = fc.getSelectedFile();

            String filename = file.getAbsolutePath();

            return filename;

        } else {

            return null;
        }
    }

    public static TableModel parse(File f) throws FileNotFoundException {

        ArrayList<String> headers = new ArrayList<String>();
        ArrayList<String> oneDdata = new ArrayList<String>();
        @SuppressWarnings("resource")
        Scanner lineScan = new Scanner(f);
        @SuppressWarnings("resource")
        Scanner s = new Scanner(lineScan.nextLine());
        s.useDelimiter(",");

        while (s.hasNext()) {

            headers.add(s.next());

        }
        while (lineScan.hasNextLine()) {

            s = new Scanner(lineScan.nextLine());
            s.useDelimiter(",");
            while (s.hasNext()) {
                oneDdata.add(s.next());
            }
        }
        String[][] data = new String[headers.size()][oneDdata.size()/headers.size()];

        for (int x = 0; x < headers.size(); x++) {
            for (int y = 0; y < data[0].length ; y++) {
                data[x][y] = oneDdata.remove(0);
            }
        }

        return new DefaultTableModel(data, headers.toArray());
    }

    public static void main(String[] args) throws FileNotFoundException {

        TableModel t = CSVParser.parse(new File(fileChose()));

        for (int x = 0; x < t.getColumnCount(); x++) {
            System.out.print(t.getColumnName(x) + " ");
        }
        System.out.println(); // Print all the data from the table.
        for (int x = 0; x < t.getRowCount(); x++) {
            for (int y = 0; y < t.getColumnCount(); y++) {
                System.out.print(t.getValueAt(x, y) + " ");
            }
            System.out.println();
        }
    }
   
   
}

Leider wird lediglich die Header-Zeile, sowie die erste Zeile danach ausgegeben. Mehr nicht. Woran kann das liegen? Sehe den Fehler einfach nicht :(

Kann mir bitte jemand helfen?
 

Enceladus271

Bekanntes Mitglied
Der Code der String[][] data erzeugt ist nicht korrekt. Dort sind Zeilen und Spalten irgendwie vertauscht worden. Versuche es mal so:
Java:
    final int rowCount = oneDdata.size() / headers.size();
    final int columnCount = headers.size();
    String[][] data = new String[rowCount][columnCount];
    for ( int x = 0; x < rowCount; x++ ) {
      for ( int y = 0; y < columnCount; y++ ) {
        data[x][y] = oneDdata.remove( 0 );
      }
    }
 

Deiuta

Mitglied
Hallo und Entschuldigung für die verspätete Antwort, hatte viel zu tun in den letzten Tagen.

Funktioniert schon viel besser, vielen Dank dafür!

Leider entspricht der Input noch nicht ganz dem Output nach dem Einlesen. Die Test-CSV sollte so aussehen:

Input.png

(Habe diese zu Testzwecken so ,,verunstaltet")

Der Output ist:

Output.png

- Kommazahlen werden auf Grund der delimiter-Definition als Abtrennungszeichen interpretiert --> setzt man den demilimiter auf ";", so kommt eine Fehlermeldung:

Fehlermeldung.png

Edit: Bei der Meldung steht noch eine IndexOutOfBoundsException

Wie schaffe ich es hier den richtigen, einheitlichen Output zu erzeugen?

Nehmt mich bitte nicht auseinander, wenn die Antwort für euch offensichtlich ist, ich bin noch Anfängerin :)
 

JStein52

Top Contributor
Es nimmt dich keiner auseinander, aber ich weiss ja nicht wie dein aktueller Code aussieht. Ich habe mal mit diesem Stand das ganze getestet und es funktioniert:

Java:
    public static TableModel parse(File f) throws FileNotFoundException {

        ArrayList<String> headers = new ArrayList<String>();
        ArrayList<String> oneDdata = new ArrayList<String>();
        @SuppressWarnings("resource")
        Scanner lineScan = new Scanner(f);
        @SuppressWarnings("resource")
        Scanner s = new Scanner(lineScan.nextLine());
        s.useDelimiter("; ");

        while (s.hasNext()) {
            headers.add(s.next());
        }
        while (lineScan.hasNextLine()) {
            s = new Scanner(lineScan.nextLine());
            s.useDelimiter("; ");
            while (s.hasNext()) {
                oneDdata.add(s.next());
            }
        }
        final int rowCount = oneDdata.size() / headers.size();
        final int columnCount = headers.size();
        String[][] data = new String[rowCount][columnCount];
        for (int x = 0; x < rowCount; x++) {
            for (int y = 0; y < columnCount; y++) {
                data[x][y] = oneDdata.remove(0);
            }
        }

        return new DefaultTableModel(data, headers.toArray());
    }

Wo genau hatte er denn bei dir die Exception geworfen ?

Edit: mein Output sieht bei einer entsprechenden Eingabedatei so aus:

Adam Eva Kain Abel
1,1 2 3 4
5 6 7 8

diese 1,1 war eben der erste Eintrag in dieser Zeile. Die anderen sind "gewöhnliche" integers

Nochmal Edit: wenn man allerdings leere Einträge im Header hat dann stimmt dein rowCount nicht mehr und im folgenden geht es dann durcheinander. Das liegt aber nicht am Delimiter !!!
 
Zuletzt bearbeitet von einem Moderator:

Enceladus271

Bekanntes Mitglied
Wie JStein schon sagte sind die leeren Einträge im Header ein Problem.
Ein weiteres Problem sind Zeilen unterschiedlicher Länge, da du in deinem Algorithmus alle Zellen zeilenübergreifend in eine einzige Liste einfügst. Dort sind dann natürlich keine Informationen mehr über die Zeilenlängen vorhanden. Du müsstest hier mit einer Liste von Listen arbeiten, etwa so:
Java:
    final List<List<String>> rows = new ArrayList<>();
    while ( lineScan.hasNextLine() ) {
       s = new Scanner( lineScan.nextLine() );
       s.useDelimiter( "," );
       List<String> row = new ArrayList<String>();
       while ( s.hasNext() ) {
         row.add( s.next() );
       }
       rows.add( row );
     }
Die Erzeugung von data bzw. des TableModels muss dann entsprechend angepasst werden.
 

JStein52

Top Contributor
Und zwar die leeren Einträge am Ende einer Eingabezeile !! Nur der Vollständigkeit halber :):)
Der Scanner liefert in so einem Fall dann auch nur drei Einträge. Bzw. halt einen weniger als der columnCount eigentlich sein sollte. (Entsprechend bei den Daten-Zeilen.)
 
Zuletzt bearbeitet:

Deiuta

Mitglied
Vielen lieben Dank für die hilfreichen Tipps, ich werde es gleich morgen mal ausprobieren und euch ein Feedback geben.

Da hab ich mir ja was angetan... :confused:
 

Deiuta

Mitglied
Hallo,

das Ganze läuft jetzt einigermaßen.

Allerdings muss ich mit den einzelnen Werten verschiedener Spalten Berechnungen durchführen.

Kann mir jemand bitte kurz erklären, wie ich zB. den ersten Wert aus der ersten Spalte mit dem ersten Wert der zweiten Spalte addiere??? Damit ich ein Gefühl dafür bekomme, wie man auf die verschiedenen Elemente zugreift.

Vielen Dank schonmal!
 

JStein52

Top Contributor
Sage uns doch bitte noch wie du es gelöst hast ? So wie von Enceladus vorgeschlagen ?

Edit: und wenn du weisst dass es funktioniert dann solltest du doch auch wissen wie du auf die Werte zugreifst, du hast sie dir doch sicher testweise ausgeben lassen ?
 

Deiuta

Mitglied
Habe jetzt folgenden Code:

Java:
public static TableModel parse(File f) throws FileNotFoundException {

        ArrayList<String> headers = new ArrayList<String>();
        ArrayList<String> oneDdata = new ArrayList<String>();
        @SuppressWarnings("resource")
        Scanner lineScan = new Scanner(f);
        @SuppressWarnings("resource")
        Scanner s = new Scanner(lineScan.nextLine());
        s.useDelimiter(";");

        while (s.hasNext()) {

            headers.add(s.next().trim());

        }
        while (lineScan.hasNextLine()) {

            s = new Scanner(lineScan.nextLine());
            s.useDelimiter(";");  //der Delimiter war falsch gesetzt, so dass die Tabelle falsch ausgegeben wurde
            while (s.hasNext()) {
                oneDdata.add(s.next().trim());  //hier hatten sich whitespaces versteckt
            }
        }
       
        final int rowCount = oneDdata.size()/ headers.size(); //Danke an Enceladus
        final int columnCount = headers.size();
        String[][] data = new String[rowCount][columnCount];
        for (int x = 0; x < rowCount; x++) {
            for (int y = 0; y < columnCount; y++) {
                data[x][y] = oneDdata.remove(0);
            }
        }

        return new DefaultTableModel(data, headers.toArray());
    }

    public static void main(String[] args) throws FileNotFoundException {

        TableModel t = CSVParser.parse(new File(fileChose()));

        for (int x = 0; x < t.getColumnCount(); x++) {
            System.out.print(t.getColumnName(x) + "|"); // das "|" ist zu Übersichtlichkeitszwecken
        }
        System.out.println();
        for (int x = 0; x < t.getRowCount(); x++) {
            for (int y = 0; y < t.getColumnCount(); y++) {
                System.out.print(t.getValueAt(x, y) + "|");
            }
            System.out.println();
        }
    }

}

Es lag hauptsächlich am Delimiter. Das einzige Problem ist nun noch Folgendes:

- kleine Tabelle mit 4 Spalten plus Inhalt --> Ausgabe wie gewünscht
- Tabelle mit 78 Spalten (das ist der eigentliche Umfang, den ich brauche) --> Ausgabe der Zeilen/Spalteninhalte wie gewünscht ABER: ab der zweiten Inhaltszeile (nicht Überschriften) hängt der mir den jewiligen Inhalt der ersten Spalte ans Ende der jeweiligen Zeile. D.h. das erste Element der jeweiligen Zeile, steht plptzlich am Ende. Hoffe das ist verständlich.

Leider sind die Daten der Tabellen vertraulich, sonst würde ich euch ein Beispiel posten.

Ich versteh das einfach nicht.....
 

JStein52

Top Contributor
Ich habe mir deinen Code genommen und eine Eingabedatei mit 78 Spalten gebastelt und es funktioniert !!!
Kann es sein dass es wieder ein Seiteneffekt bei deinen Eingabedaten ist ??
 

Deiuta

Mitglied
Hallo JStein52,

du hast Recht! Habe es gerade auch nochmals mit einer Test-CSV diesen Umfanges versucht und es funktioniert tatsächlich! Es liegt also wirklich an den Eingabedaten. Nun muss ich nurnoch darauf kommen, was an denen anders ist und zu dieser Ausgabe führt.

Könntest du, oder jemand Anderes mit vielleicht zeigen, wie ich nun Berechnungen mit Werten aus verschiedenen Spalten durchführen kann? Kann ja schlecht jeden Wert/jede Spalte manuell in eine Variable speichern, oder?

Vielen Dank schonmal!

Habe übrigens durch Eure Hilfe schon sehr viel dazu gelernt.

EDIT: kann ich das über den Zugriff auf dieses Array machen? Wenn ja, wie?
Java:
...
String[][] data = new String[rowCount][columnCount];
        for (int x = 0; x < rowCount; x++) {
            for (int y = 0; y < columnCount; y++) {
                data[x][y] = oneDdata.remove(0);
            }
...
 
Zuletzt bearbeitet von einem Moderator:

JStein52

Top Contributor
Ja, du kannst dir z.B. aus diesem String-Array eine double-Array machen etwa so:

Code:
double[][] dblData = new double[rowCount][columnCount];
        for (int x = 0; x < rowCount; x++) {
            for (int y = 0; y < columnCount; y++) {
                dblData[x][y] = Double.parseDouble(oneDdata.remove(0));

oder du wandelst immer an den Stellen wo du damit rechenen willst die einzelnen Operanden von String nach double um, z.B.
Code:
double ergebnis = Double.parseDouble(data[x][y]) + Double.parseDouble(data[x][y+1]);
 

Deiuta

Mitglied
Zu früh gefreut...

angenommen ich möchte die Werte in einer anderen Klasse ,,Statistics" aufrufen (nach Deiner Methode) und daraus bsplw. den Durchschnitt berechnen, etwa so:

Java:
public static double mean(ArrayList<Double> val){
       
       

             double sum = 0;
            
             for (double d : val)
                 sum += d;

             return sum/val.size();
        }

...wie müsste ich das anstellen?

Bin völlig überfordert
 

JStein52

Top Contributor
:) Ok, kriegen wir schon. Du machst dir z.B. in der Klasse CVSParser eine (oder mehrere ) Getter-Methode die dir
die gewünschten Daten (z.B. alle Werte einer bestimmten Spalte oder je nach dem was du brauchst) als List<Double>
zurückliefert. In dieser Getter-Methode wandelst du deine Strings so wie oben beschrieben in double-Werte um. Wäre das eine Idee ?
 

Deiuta

Mitglied
Hallo, ich wieder :)
Leider finde ich im Internet nichts passendes dazu, daher hier ein neues Problem:

Wie kann ich es umsetzen, dass erkannt wird, wenn eine Zeile (Datensatz) einen gewissen String (zB "ABC") enthält und diesen Datensatz daraufhin beim Einlesen auslässt?

Danke :)
 

Maggot

Bekanntes Mitglied
Dort wo du den String einliest fragst du ab ob der String etwas bestimmtes enthält (.contains("ABC")) und dann lasst du das einfach aus.
 

Deiuta

Mitglied
Da ist mein Problem. Wie lasse ich denn die ganze Zeile/den ganzen Datensatz aus? Habe irgendwie kein Code-Beispiel gefunden, welches ich auf mein Problem anwenden könnte.
 

JStein52

Top Contributor
Vielleicht so:
Java:
    ...
    String[][] data = new String[rowCount][columnCount];
            for (int x = 0; x < rowCount; x++) {
                for (int y = 0; y < columnCount; y++) {
                    data[x][y] = oneDdata.remove(0);
                    if (data[x][y].contains("ABC") {
                        x--;     // wieder eine Zeile zurückhupfen
                        break; // und aus der Schleife fuer die Spalten rausgehen
                    }
                }
    ...

Danach stimmt allerdings der rowCount nicht mehr ! Den müsstest du evtl. auch noch korrigieren. Ich weiss, es wäre noch schöner wenn man es weiter oben beim lineScan machen würde
 

JStein52

Top Contributor
Besser so:

Java:
while (lineScan.hasNextLine()) {
            String line = lineScan.nextLine();
            if (line.contains("ABC") {
               continue;
            }
            s = new Scanner(line);
            s.useDelimiter(";");  //der Delimiter war falsch gesetzt, so dass die Tabelle falsch ausgegeben wurde
            while (s.hasNext()) {
                oneDdata.add(s.next().trim());  //hier hatten sich whitespaces versteckt
            }
        }
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Ras Unterschied zwischen parser xml and api xml Java Basics - Anfänger-Themen 7
B Parser dynamisieren Java Basics - Anfänger-Themen 7
W Einfachen, ein beliebiges Zeichen oft erkennenden Regex Parser selber schreiben - wie vorgehen? Java Basics - Anfänger-Themen 12
U DOM Parser, kleine Frage Java Basics - Anfänger-Themen 29
H java date-time parser Java Basics - Anfänger-Themen 1
X SAX Parser, wie weit ist der eigentlich? Java Basics - Anfänger-Themen 6
O HTML -> BBCode Parser? Java Basics - Anfänger-Themen 3
J kleiner Fehler im FAQ Parser für mathematische Formeln Java Basics - Anfänger-Themen 5
H Welcher Html-Parser? Java Basics - Anfänger-Themen 8
M htlm parser Java Basics - Anfänger-Themen 8
U Benötige ich einen Parser? Java Basics - Anfänger-Themen 2
T Parser mit switch "Weg" ausgeben? Java Basics - Anfänger-Themen 5
A html parser Java Basics - Anfänger-Themen 5
T XML Parser Java Basics - Anfänger-Themen 21
data89 Frage zum FAQ-'Parser für mathematische Formeln' Java Basics - Anfänger-Themen 4
T Wofür Parser?? Java Basics - Anfänger-Themen 39
A Gettext-Parser: Rad neu erfinden Java Basics - Anfänger-Themen 6
G Eigener Parser Java Basics - Anfänger-Themen 4
G guter Parser Java Basics - Anfänger-Themen 4
G Parser liefert StackOverflow error Java Basics - Anfänger-Themen 6
L URL Parser (String zusammensetzen) Java Basics - Anfänger-Themen 2
G If-Parser + Interpreter Java Basics - Anfänger-Themen 9
E HTML Parser Java Basics - Anfänger-Themen 8
B Parser HTML Java Basics - Anfänger-Themen 10
J Noch ein Parser Problem Java Basics - Anfänger-Themen 7
J Richtigen Parser wählen Java Basics - Anfänger-Themen 2
M.C.S. Parser: Flut von Variablen und if-Conditions eindämmen Java Basics - Anfänger-Themen 4
A Parser Java Basics - Anfänger-Themen 4
D Array List mit Objekten sortieren Java Basics - Anfänger-Themen 2
J Array.list vergleichen Java Basics - Anfänger-Themen 1
B Vektor vs List Java Basics - Anfänger-Themen 4
volcanos Addition -> List<Integer> mit Arrays.asList() versus List<Integer>ArrayList<>() Java Basics - Anfänger-Themen 14
H Interface Wieso "List<String> list = new ArrayList<>[…]" Java Basics - Anfänger-Themen 4
T Linked List set-Methode Java Basics - Anfänger-Themen 2
volcanos List & ArrayList nach Familiennamen abfragen Java Basics - Anfänger-Themen 57
berserkerdq2 Ich gebe eine ArrayList als List zurück per MEthode, wie kann ich nun aber die ArrayList speichern? Java Basics - Anfänger-Themen 46
L Datentypen Array List Java Basics - Anfänger-Themen 9
J Java List, Bitte um Hilfe Java Basics - Anfänger-Themen 15
J Java List, bitte um Hilfe Java Basics - Anfänger-Themen 3
F GSON file mit einer List erstellen Java Basics - Anfänger-Themen 2
B Interface List - Objekt übergeben? Einzelnes Objekt geht, aber Liste nicht? Java Basics - Anfänger-Themen 4
O Collections.sort und List.sort mit Lambda Verwirrung Java Basics - Anfänger-Themen 5
J String Array zu Map<Character, List<Character>> mit Streams Java Basics - Anfänger-Themen 1
G Linked list, Methode zum Vertauschen von Elementen Java Basics - Anfänger-Themen 14
I csv auslesen, mittels List Java Basics - Anfänger-Themen 18
C Collections List über Interface zugreifen Java Basics - Anfänger-Themen 32
I Methoden List.contains() beim 2. Element = true Java Basics - Anfänger-Themen 1
N HashMap in List good practice? Java Basics - Anfänger-Themen 2
B SWAP List; Liste neu anordnen Java Basics - Anfänger-Themen 4
W Stream Array List - Frage Java Basics - Anfänger-Themen 5
E Interface List nicht als Collection an erkannt. Java Basics - Anfänger-Themen 14
X Array List geordnet ausgeben. (JSF und JAVA) Java Basics - Anfänger-Themen 1
D new arraylist (List) dynamisch erstellen Java Basics - Anfänger-Themen 1
Yjuq Generic Methode - Wie muss die List Definition aussehen? Java Basics - Anfänger-Themen 3
M List<String> auswählen Java Basics - Anfänger-Themen 42
F In List Rekursiv suchen Java Basics - Anfänger-Themen 12
B Unterschied zwischen (List<T> a) und (T[] a) Java Basics - Anfänger-Themen 7
T HashSet in List-Object Java Basics - Anfänger-Themen 5
B ENUM to List<String> konvertieren Java Basics - Anfänger-Themen 2
E Array-list mit einer bestimmten Länge Java Basics - Anfänger-Themen 17
B Sorting List und Remove Java Basics - Anfänger-Themen 2
B String: suche nach Wörter und in List<String> speichern Java Basics - Anfänger-Themen 3
M Methode überladen - Array List Java Basics - Anfänger-Themen 5
L LIST.ADD Java Basics - Anfänger-Themen 2
M XWPF - Bullet Point list erstellen Java Basics - Anfänger-Themen 1
I <List> sortieren Java Basics - Anfänger-Themen 2
N Klassen List-Art Java Basics - Anfänger-Themen 5
S List<T<X,Y> sortieren Java Basics - Anfänger-Themen 5
Salo Datentypen "Doppelt" List(e) ("gesucht") Java Basics - Anfänger-Themen 6
F .csv Export aus einer list Java Basics - Anfänger-Themen 25
T KlausurÜbung- Förderband-Linked List Java Basics - Anfänger-Themen 53
D Komischer Fehler nach <Integer> List Java Basics - Anfänger-Themen 2
B in einem abstrakten Set ,Elemente einer einfache verkettete List epeichern Java Basics - Anfänger-Themen 13
T List und ArrayList Java Basics - Anfänger-Themen 3
UnityFriday method getPrevious in class List<ContentType> cannot be applied to given types Java Basics - Anfänger-Themen 29
hooked Verkettete Liste / linked list Java Basics - Anfänger-Themen 2
T Datentypen InputStream to list of Int (or similar) Java Basics - Anfänger-Themen 4
V Erste Schritte Dateinamen aus einer FIle[] in eine List Java Basics - Anfänger-Themen 11
S Methoden Linked List Methoden können nicht aufgerufen werden Java Basics - Anfänger-Themen 1
U JAXB - List wird nicht ausgefüllt Java Basics - Anfänger-Themen 1
L Linked List - Array List Java Basics - Anfänger-Themen 2
J Einfach verkettet List: Ausgabe ohne null Java Basics - Anfänger-Themen 11
D Bestimmten Wert aus Array List ausgeben Java Basics - Anfänger-Themen 7
V Personenverwaltung mit List<>, falsche Ausgaben Java Basics - Anfänger-Themen 5
M List befüllen Java Basics - Anfänger-Themen 3
S Datentypen List.toString wirft NullPointerException Java Basics - Anfänger-Themen 5
P Anlegen und Abfragen von Array List Java Basics - Anfänger-Themen 4
S Element von List<E> in String umwandeln Java Basics - Anfänger-Themen 3
A Wie nutze ich List<List<String>> Java Basics - Anfänger-Themen 4
M Endlos schleife in List Java Basics - Anfänger-Themen 5
P Zufallszahlen ohne zahlen einer List Java Basics - Anfänger-Themen 21
C Array List mit String vergleichen und Fehlermeldung ausgeben Java Basics - Anfänger-Themen 6
S Probleme bei Ausgabe von rekursiver Methode (List) Java Basics - Anfänger-Themen 16
T Tabstopp in AWT-List? Java Basics - Anfänger-Themen 8
P Doppelte Einträge in eine List Java Basics - Anfänger-Themen 5
M Wozu Upcasting? Am Beispiel List = ArrayList Java Basics - Anfänger-Themen 2
A List mit integern füllen Java Basics - Anfänger-Themen 4
D sortieren von List<> Java Basics - Anfänger-Themen 2
B List - Drag&Drop Java Basics - Anfänger-Themen 8
SexyPenny90 Implementierung einer doubly linked list Java Basics - Anfänger-Themen 5

Ähnliche Java Themen

Neue Themen


Oben