it-swarm.com.de

Arbeiten mit einer Liste von Listen in Java

Ich versuche, eine CSV-Datei in eine Liste von Listen (von Strings) einzulesen, um Daten aus einer Datenbank abzurufen, eine neue Liste mit neuen Datenlisten zu erstellen und diese Liste dann weiterzuleiten in eine neue CSV-Datei geschrieben. Ich habe überall nachgesehen und kann anscheinend kein Beispiel finden, wie es geht

Ich möchte lieber keine einfachen Arrays verwenden, da die Dateien unterschiedlich groß sind und ich nicht wissen kann, was für die Abmessungen der Arrays verwendet werden soll. Ich habe keine Probleme mit den Dateien. Ich bin mir einfach nicht sicher, wie ich mit der Liste der Listen umgehen soll.

Die meisten Beispiele, die ich gefunden habe, werden mehrdimensionale Arrays erstellen oder Aktionen innerhalb der Schleife ausführen, die die Daten aus der Datei liest. Ich weiß, dass ich das kann, aber ich möchte objektorientierten Code schreiben. Wenn Sie einen Beispielcode angeben oder mich auf eine Referenz verweisen könnten, wäre das großartig.

45
Rob-0
ArrayList<ArrayList<String>> listOLists = new ArrayList<ArrayList<String>>();
ArrayList<String> singleList = new ArrayList<String>();
singleList.add("hello");
singleList.add("world");
listOLists.add(singleList);

ArrayList<String> anotherList = new ArrayList<String>();
anotherList.add("this is another list");
listOLists.add(anotherList);
117
tster

Wenn Sie wirklich wissen möchten, dass CSV-Dateien perfekt in Java verarbeitet werden, ist es nicht gut, wenn Sie versuchen, den CSV-Reader/Writer selbst zu implementieren. Überprüfen Sie unten heraus. 

http://opencsv.sourceforge.net/

Wenn Ihr CSV-Dokument doppelte Anführungszeichen oder Zeilenumbrüche enthält, haben Sie Schwierigkeiten. 

Um sich zunächst mit dem objektorientierten Ansatz vertraut zu machen, hilft Ihnen die Implementierung einer anderen Implementierung (von Java). Und ich denke, dass es nicht gut ist, eine Zeile in einer Liste zu verwalten. CSV erlaubt keine Differenzspaltengröße. 

15
xrath

Hier ist ein Beispiel, das eine Liste von CSV-Zeichenfolgen in eine Liste von Listen liest, diese Liste von Listen durchläuft und die CSV-Zeichenfolgen wieder an die Konsole ausgibt.

import Java.util.ArrayList;
import Java.util.List;

public class ListExample
{
    public static void main(final String[] args)
    {
        //sample CSV strings...pretend they came from a file
        String[] csvStrings = new String[] {
                "abc,def,ghi,jkl,mno",
                "pqr,stu,vwx,yz",
                "123,345,678,90"
        };

        List<List<String>> csvList = new ArrayList<List<String>>();

        //pretend you're looping through lines in a file here
        for(String line : csvStrings)
        {
            String[] linePieces = line.split(",");
            List<String> csvPieces = new ArrayList<String>(linePieces.length);
            for(String piece : linePieces)
            {
                csvPieces.add(piece);
            }
            csvList.add(csvPieces);
        }

        //write the CSV back out to the console
        for(List<String> csv : csvList)
        {
            //dumb logic to place the commas correctly
            if(!csv.isEmpty())
            {
                System.out.print(csv.get(0));
                for(int i=1; i < csv.size(); i++)
                {
                    System.out.print("," + csv.get(i));
                }
            }
            System.out.print("\n");
        }
    }
}

Ich denke, es ist ziemlich einfach. Nur ein paar Punkte zu beachten:

  1. Ich empfehle, beim Erstellen von Listenobjekten "Liste" anstelle von "ArrayList" auf der linken Seite zu verwenden. Es ist besser, die Schnittstelle "List" zu durchlaufen, da Sie dann, wenn Sie später auf die Verwendung von Vector wechseln müssen (z. B. jetzt synchronisierte Listen), nur die Zeile mit der Anweisung "new" ändern müssen. Unabhängig davon, welche Implementierung der Liste Sie verwenden, z. Ob Vector oder ArrayList, Sie geben immer nur List<String> weiter.

  2. Im ArrayList-Konstruktor können Sie die Liste leer lassen. Sie hat standardmäßig eine bestimmte Größe und wächst dann dynamisch nach Bedarf. Aber wenn Sie wissen, wie groß Ihre Liste sein könnte, können Sie manchmal etwas Leistung sparen. Wenn Sie beispielsweise wüssten, dass Ihre Datei immer 500 Zeilen enthalten würde, können Sie Folgendes tun:

List<List<String>> csvList = new ArrayList<List<String>>(500);

Auf diese Weise würden Sie niemals Bearbeitungszeit verschwenden und darauf warten, dass Ihre Liste dynamisch wächst. Aus diesem Grund übergebe ich "linePieces.length" an den Konstruktor. Normalerweise keine große Sache, aber manchmal hilfreich.

Hoffentlich hilft das!

10

Das von @tster bereitgestellte Beispiel zeigt, wie eine Liste mit einer Liste erstellt wird. Ich werde ein Beispiel für das Durchlaufen einer solchen Liste geben.

Iterator<List<String>> iter = listOlist.iterator();
while(iter.hasNext()){
    Iterator<String> siter = iter.next().iterator();
    while(siter.hasNext()){
         String s = siter.next();
         System.out.println(s);
     }
}
5

So etwas würde zum Lesen funktionieren:

String filename = "something.csv";
BufferedReader input = null;
List<List<String>> csvData = new ArrayList<List<String>>();
try 
{
    input =  new BufferedReader(new FileReader(filename));
    String line = null;
    while (( line = input.readLine()) != null)
    {
        String[] data = line.split(",");
        csvData.add(Arrays.toList(data));
    }
}
catch (Exception ex)
{
      ex.printStackTrace();
}
finally 
{
    if(input != null)
    {
        input.close();
    }
}
3
Droo

Zweitens, was Xrath gesagt hat - es ist besser, wenn Sie eine vorhandene Bibliothek für das Lesen/Schreiben von CSV verwenden.

Wenn Sie planen, Ihr eigenes Framework zu rollen, würde ich auch vorschlagen, List<List<String>> nicht als Implementierung zu verwenden. Sie könnten wahrscheinlich besser CSVDocument und CSVRow Klassen implementieren (die intern List<CSVRow> bzw. List<String> verwenden können). machen Sie nur eine unveränderliche Liste oder ein Array verfügbar. 

Wenn Sie einfach List<List<String>> verwenden, bleiben zu viele ungeprüfte Edge-Fälle übrig, und Sie verlassen sich auf Implementierungsdetails. Wie werden beispielsweise Header getrennt von den Daten gespeichert? oder sind sie in der ersten Zeile des List<List<String>>? Was ist, wenn ich nicht über den Index, sondern über die Spaltenüberschrift auf die Daten zugreifen möchte?

was passiert, wenn man Dinge nennt wie:

// reads CSV data, 5 rows, 5 columns 
List<List<String>> csvData = readCSVData(); 
csvData.get(1).add("extraDataAfterColumn"); 
// now row 1 has a value in (nonexistant) column 6
csvData.get(2).remove(3); 
// values in columns 4 and 5 moved to columns 3 and 4, 
// attempting to access column 5 now throws an IndexOutOfBoundsException.

Sie können versuchen, all dies zu überprüfen, wenn Sie die CSV-Datei herausschreiben, und dies kann in einigen Fällen funktionieren. In anderen Fällen werden Sie den Benutzer jedoch auf eine Ausnahme aufmerksam machen, die weit von der Stelle entfernt ist, an der die fehlerhaften Änderungen vorgenommen wurden schwieriges Debugging.

2
Nate

Dies ist auch ein Beispiel für das Drucken von List of List mithilfe von advanced for loop:

public static void main(String[] args){
        int[] a={1,3, 7, 8, 3, 9, 2, 4, 10};
        List<List<Integer>> triplets;
        triplets=sumOfThreeNaive(a, 13);
        for (List<Integer> list : triplets){
            for (int triplet: list){
                System.out.print(triplet+" ");
            }
            System.out.println();
        }
    }
0
Mona Jalal
 public class TEst {

    public static void main(String[] args) {

        List<Integer> ls=new ArrayList<>();
        ls.add(1);
        ls.add(2);
        List<Integer> ls1=new ArrayList<>();
        ls1.add(3);
        ls1.add(4);
        List<List<Integer>> ls2=new ArrayList<>();
        ls2.add(ls);
        ls2.add(ls1);

        List<List<List<Integer>>> ls3=new ArrayList<>();
        ls3.add(ls2);


        methodRecursion(ls3);
    }

    private static void methodRecursion(List ls3) {
        for(Object ls4:ls3)
        {
             if(ls4 instanceof List)    
             {
                methodRecursion((List)ls4);
             }else {
                 System.out.print(ls4);
             }

        }
    }

}
0
jitendra rawat