# CSV Daten in ArrayList speichern und sortieren..



## chillazz (19. Dezember 2008)

Guten Abend,

ich habe ein Problem und zwar geht es darum:
Ich will eine CSV Datei auslesen und in eine ArrayList speichern... Dies funktioniert auch... Ich will jetzt aber diese ArrayList sortieren (habe ich auch geschaft aber leider sortiert er mir immer nur die erste Spalte der Datei). Ich würde aber gerne die dritte Spalte SOrtiert haben.

CSV Dateiinhalt sieht so aus:
Frequenz;Kanal;Qualitaet;Programm;Anbieter
198500;8a;58;PHOENIX;ARD
198500;8b;58;Bayerisches FS;ARD
198500;8c;58;SWR Fernsehen RP;ARD
602000;37c;91;arteEinsExtra;ARD
658000;44a;10;Bayerisches FS;SWR

Mein Quellcode bis jetzt:
	public void readFileData() {

		// Einlesen des Files und spliten
		FileReader myFile = null;
		BufferedReader buff = null;
		final List<String> lines = new ArrayList<String>();

		try {
			myFile = new FileReader("Kanalscan.csv");
			buff = new BufferedReader(myFile);
			String line;
			while ((line = buff.readLine()) != null) {
				System.out.println(line); // kontrolle was eingelesen

				lines.add(line);
			}

			Collections.sort(lines, Collator.getInstance());
			System.out.println(lines);

		} catch (IOException e) {
			System.err.println("Error2 :" + e);
		} finally {
			try {
				buff.close();
				myFile.close();
			} catch (IOException e) {
				System.err.println("Error2 :" + e);
			}
		}

		final String[][] valuesArray = new String[lines.size()][];
		int cnt = 0;
		for (final String line : lines) {
			valuesArray[cnt++] = line.split(",");
		}



		// Ausgabe des Array
//		for (String[] arr : valuesArray) {
//			System.out.println(Arrays.toString(arr));
//			
//		}

	}

Es soll am Ende einfach nach "Qualität" sortiert werden.
Es wäre echt super wenn mir jemand dabei helfen könnte weil ich absolut keine idee habe.

Liebe Grüße


----------



## normaler_spinner (20. Dezember 2008)

Hi,

du speicherst immer eine Zeile in der ArrayList, ergo kann er natürlich auch nur nach der "ersten" Spalte sortieren. Im Prinzip kennt deine ArrayList ja nicht mehr die einzelnen Spalten sondern nur die Zeilen


----------



## chillazz (20. Dezember 2008)

okay und wie muss ich es programmieren damit es geht?


----------



## procurve (20. Dezember 2008)

Schau dir mal Collections.sort() an.

Dann musst du nur noch eine funktion schrieben, die du als comparator an die sort()-Methode übergibst.


----------



## Florian Strienz (20. Dezember 2008)

Gehe folgendermaßen vor:

Schreib dir erst mal ein Bean (eine String Variable für jede Spalte mit getter und Setter Methoden), dass deine Daten der csv Datei abbildet. Also eine Zeile deiner Datei.

Dann speicher Objekte (eins pro Zeile deiner Datei) dieses Beans in deiner ArrayListe.

Dann schreib dir ein Comparator für dein Bean, der nach der Spalte die du möchstest sortiert und den du dann mit der statischen Sortiermethode der Klasse Collections anwendest. 

^^ 

So musst du vorgehen um alles sauber zu implementieren.

Gruß
Flo


----------



## chillazz (22. Dezember 2008)

alles klar..super..ich versuch es...ansonsten meld ich mich wieder


----------



## chillazz (22. Dezember 2008)

kannst du mir bitte mal schreiben wie ich aus der csv datei einzelme spalten der set methode übergeben kann?
also wie kann ich eine spalte ansprechen?


----------



## normaler_spinner (22. Dezember 2008)

Aus der CSV-Datei glaub ich gar nicht. Wenn du aber schon zeilenweise einliest, dann extrahier doch mit einem StringTokenizer die einzelnen Spalten aus der gerade eingelesenen Zeile


----------



## chillazz (22. Dezember 2008)

könntest du mir da bissl quellcode zu verfügung stellen?
bin sehr neu in der java welt..


----------



## chillazz (22. Dezember 2008)

also mein problem ist einfach dass ich eine csv datei einlese...
funktioniert auch..
die mag ich speichern (wo ist mir egal also ob. liste oder string)
aber dann mag ich nach der 3 spalte sortieren lassen...

hast du ne gute idee mit bissl code?


----------



## normaler_spinner (22. Dezember 2008)

so kannst du die Spalten an die einzelnen setter übergeben


```
String x = "198500;8a;58;PHOENIX;ARD";
		StringTokenizer st = new StringTokenizer(x, ";");
		setSpalte1(st.nextToken());
		setSpalte2(st.nextToken());
		setSpalte3(st.nextToken());
		setSpalte4(st.nextToken());
		setSpalte5(st.nextToken());
```

gibt da durchaus elegantere Lösungen aber zum allgemeinen Verständnis sollte dies mal so reichen.


----------



## chillazz (22. Dezember 2008)

okay super..
hab es jetzt an mich angepasst...
	public void readFileData() {

		// Einlesen des Files und spliten
		FileReader myFile = null;
		BufferedReader buff = null;
		ArrayList<Bean> lines = new ArrayList<Bean>();

		try {
			myFile = new FileReader("Kanalscan.csv");
			buff = new BufferedReader(myFile);
			String line;
			while ((line = buff.readLine()) != null) {
				System.out.println(line); // kontrolle was eingelesen
				Bean bean = new Bean();
				StringTokenizer st = new StringTokenizer(line, ";");
				bean.setFrequenz(st.nextToken());
				bean.setKanal(st.nextToken());
				bean.setQualität(st.nextToken());
				bean.setProgramm(st.nextToken());
				bean.setAnbieter(st.nextToken());
				lines.add(bean);
			}

und wie lass ich jetzt noch nach der 3ten spalte sortieren und in der konsole ausgeben?
mit code wäre ideal..

danke vielmals...


----------



## chillazz (23. Dezember 2008)

Hallo,

erstmal mein Code:

```
package pack;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.StringTokenizer;

import javax.swing.JWindow;

public class Testzwecke implements Comparator<Bean> {
	public void readFileData() {

		// Einlesen des Files und spliten
		FileReader myFile = null;
		BufferedReader buff = null;
		ArrayList lines = new ArrayList();

		try {
			myFile = new FileReader("Kanalscan.csv");
			buff = new BufferedReader(myFile);
			String line;
			while ((line = buff.readLine()) != null) {
				System.out.println(line); // kontrolle was eingelesen
				Bean bean = new Bean();
				StringTokenizer st = new StringTokenizer(line, ";");
				bean.setFrequenz(st.nextToken());
				bean.setKanal(st.nextToken());
				bean.setQualität(st.nextToken());
				bean.setProgramm(st.nextToken());
				bean.setAnbieter(st.nextToken());
				lines.add(bean);
			}

			// Collections.sort(lines, compare));
		} catch (IOException e) {
			System.err.println("Error2 :" + e);
		} finally {
			try {
				buff.close();
				myFile.close();
			} catch (IOException e) {
				System.err.println("Error2 :" + e);
			}
		}
	}

	public int compare(Bean o1, Bean o2) {
		if (o1.getQualität() > o2.getQualität())
			return 1;
		if (o1.getQualität() < o2.getQualität())
			return -1;
		else
			return 0;
	}
}
```

ich hab einpaar probleme und wollte fragen ob ihr mir bitte weiterhelfen könnt.
1. meine compare methode funktioniert nur wenn die getmethode ein "int,char" ist..
aber wenn ich dies änder funktioniert mein "nextToken" nicht mehr.
was für eine lösung gibt es da?

2. hab ich die compare metode richtig programmiert? ich möchte dass nach "qualität" sortiert wird... Wenn ja wie übergebe ich richtig die parameter der Collection.sort()

Bitte noch neu in Java wäre super wenn mit jemand helfen könnte da ich wirklich nicht mehr weiter weiß....


----------



## normaler_spinner (23. Dezember 2008)

warst eigentlich schon ganz nah dran:


```
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;

public class CSV{

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// Einlesen des Files und spliten
		FileReader myFile = null;
		BufferedReader buff = null;
		ArrayList<Bean> lines = new ArrayList<Bean>();

		try {
			myFile = new FileReader("Test.txt.txt");
			buff = new BufferedReader(myFile);
			String line;
			while ((line = buff.readLine()) != null) {
				System.out.println(line); // kontrolle was eingelesen
				Bean bean = new Bean();
				StringTokenizer st = new StringTokenizer(line, ";");
				bean.setFrequenz(st.nextToken());
				bean.setKanal(st.nextToken());
				bean.setQualitaet(st.nextToken());
				bean.setProgramm(st.nextToken());
				bean.setAnbieter(st.nextToken());
				lines.add(bean);
			}
			 Collections.sort(lines);
		} catch (IOException e) {
			System.err.println("Error2 :" + e);
		} finally {
			try {
				buff.close();
				myFile.close();
			} catch (IOException e) {
				System.err.println("Error2 :" + e);
			}
		}
	}

}
```

und deine Beans:

```
public class Bean implements Comparable<Bean>{
	
	String frequenz;
	
	String kanal;
	
	String qualitaet;
	
	String programm;
	
	String anbieter;
	
	public Bean(){
		
	}

	public String getFrequenz() {
		return frequenz;
	}

	public void setFrequenz(String frequenz) {
		this.frequenz = frequenz;
	}

	public String getKanal() {
		return kanal;
	}

	public void setKanal(String kanal) {
		this.kanal = kanal;
	}

	public String getQualitaet() {
		return qualitaet;
	}

	public void setQualitaet(String qualitaet) {
		this.qualitaet = qualitaet;
	}

	public String getProgramm() {
		return programm;
	}

	public void setProgramm(String programm) {
		this.programm = programm;
	}

	public String getAnbieter() {
		return anbieter;
	}

	public void setAnbieter(String anbieter) {
		this.anbieter = anbieter;
	}

	@Override
	public int compareTo(Bean o) {
		return qualitaet.compareTo(o.getQualitaet());
	}
}
```

vielleicht noch als kleine Anmerkung: Umlaute gehören nicht in Variablenbezeichnungen


----------



## normaler_spinner (23. Dezember 2008)

achja die Ausgabe auf der Console:

in der Klasse Bean legst du eine Methode an z.B:


```
public String toString(){
		return frequenz + "\t" + kanal  + "\t" + qualitaet  + "\t" + anbieter; 
	}
```

dann musst du dür die Ausgabe nur noch folgendes implementieren


```
for(int i=0;i<lines.size();i++){
				 System.out.println(lines.get(i));
			 }
```


----------



## chillazz (23. Dezember 2008)

super vielen dank...
läuft einwandfrei...

die letzte frage welche klassen oder methoden gibt es denn um die ausgabe schön formatiert auszugeben..
also unter frequenz dass immer der wert steht, unter qualität dann genau der qualität wert?

weil momentan hab ich die ausgabe:

```
for (int i = 0; i < lines.size(); i++) {
				System.out.println(lines.get(i));
			}
```


----------



## chillazz (23. Dezember 2008)

niemand eine idee?


----------



## normaler_spinner (23. Dezember 2008)

Ich denke jetzt mal das ist so leicht, dass du dir das selber erarbeiten kannst, du musst doch nur noch die Ausgabe ausrichten


----------



## chillazz (23. Dezember 2008)

ja klar...
denke auch dass es net so schwer ist..
kannst du mir nur sagen welche methoden schon von java vordefinerit sind für sowas?


----------

