# Welche Datenstruktur?



## GerhardSchröder (17. Aug 2012)

Hallo zusammen,

ich habe eine csv-Datei, die ca. 800 Datensätze enthält.
Der Aufbau ist eigentlich ganz simpel: Postleitzahl;Straße;Stadt;Ortsteil

Jetzt würde ich gerne ein kleines Tool schreiben, bei dem ich den Straßennamen eingeben kann und dann alle Straßen mit diesem Namen gefunden werden.

Mein Problem besteht jetzt darin, dass nicht weiß, wie ich die Datensätze in eine vernünftig Datenstruktur überführen soll.
Auf der Datei selber möchte ich nicht so gerne arbeiten, damit das Teil flexibel bleibt und man vielleicht auch mal mehr Datensätze verarbeiten kann.

Wie würdet Ihr das lösen? Vielleicht sogar mit einer Datenbank im Hintergrund?

Viele Grüße


----------



## Sym (17. Aug 2012)

Ich würde dafür eine In-Memory-DB verwenden. Der Vorteil ist, dass Du damit z.B. auch schnell Wildcard-Suchen unterstützt.

Mach Die da eine Tabelle rein und gut ists. Dann einfach direkt gegen die DB entwickeln.


----------



## maki (17. Aug 2012)

> Der Aufbau ist eigentlich ganz simpel: Postleitzahl;Straße;Stadt;Ortsteil


Klingt für mich so, als ob da eine Abstraktion (Klasse) "Addresse" angebracht wäre.


----------



## Landei (17. Aug 2012)

Vielleicht lohnt sich auch eine Bibliothek, kurzes googeln hat Java CSV Library | Free Development software downloads at SourceForge.net  zu Tage gefördert. Auch wenn CSV auf den ersten Blick einfach erscheint, gibt es doch eins, zwei Stolperfallen (escapen, quoten...)


----------



## GerhardSchröder (17. Aug 2012)

Hallo zusammen,

erst einmal vielen Dank für das Feedback.



Sym hat gesagt.:


> Ich würde dafür eine In-Memory-DB verwenden. Der Vorteil ist, dass Du damit z.B. auch schnell Wildcard-Suchen unterstützt.
> 
> Mach Die da eine Tabelle rein und gut ists. Dann einfach direkt gegen die DB entwickeln.



Wenn ich das richtig verstanden habe, dann sind die Daten aber nicht persistent und müsste die Datei bei jedem Programmstart einlesen. 
Für 800 Datensätze sicherlich kein Problem, aber bei mehreren Tausend oder noch mehr weiß ich nicht, ob dass wirklich sinnvoll ist.



maki hat gesagt.:


> Klingt für mich so, als ob da eine Abstraktion (Klasse) "Addresse" angebracht wäre.



Das war auch meine erste Idee.
Die habe ich aber wieder verworfen, da ich so doch für jeden Eintrag in der Datei ein Objekt erzeugen würde. Das scheint mir auch sehr ineffizient zu sein.



Landei hat gesagt.:


> Vielleicht lohnt sich auch eine Bibliothek, kurzes googeln hat Java CSV Library | Free Development software downloads at SourceForge.net  zu Tage gefördert. Auch wenn CSV auf den ersten Blick einfach erscheint, gibt es doch eins, zwei Stolperfallen (escapen, quoten...)



Vielleicht verstehe ich das jetzt auch falsch, aber die Frage war eigentlich nicht, wie ich die Datei einlesen soll, sondern eher wie ich das eingelesene abspeichern soll, damit ich damit vernünftig arbeiten kann.

Viele Grüße


----------



## Landei (17. Aug 2012)

GerhardSchröder hat gesagt.:


> Vielleicht verstehe ich das jetzt auch falsch, aber die Frage war eigentlich nicht, wie ich die Datei einlesen soll, sondern eher wie ich das eingelesene abspeichern soll, damit ich damit vernünftig arbeiten kann.



Ich würde dir trotzdem zu einer Bibliothek raten, jedenfalls wenn du die Datei nicht selbst erzeugst. 

Ansonsten stimme ich mit maki überein, und würde eine entsprechende Klasse benutzen. 

Vielleicht gibt es ja sowas ähnliches wie JAXB auch für CVS (oder du kannst statt CSV XML verwenden), dann gibt's die "Übersetzung" sogar gratis.


----------



## GerhardSchröder (17. Aug 2012)

Mir ist da gerade noch etwas anderes eingefallen.

Was würdet Ihr von einem Baum halten?
Als Ebenen von Oben nach unten stelle ich mir Ort, Ortsteil, PLZ und Straße vor.
Allerdings müsste ich dann immer bis zur Ebene Straße runter und da suchen. Bei großen Datenmengen scheint mir das auch nicht optimal zu sein.

Im Prinzip ist es ja wie bei einem Telefonbuch.
Was würde man denn hier für eine Datenstruktur nutzen?


----------



## GerhardSchröder (17. Aug 2012)

Landei hat gesagt.:


> Ich würde dir trotzdem zu einer Bibliothek raten, jedenfalls wenn du die Datei nicht selbst erzeugst.
> 
> Ansonsten stimme ich mit maki überein, und würde eine entsprechende Klasse benutzen.
> 
> Vielleicht gibt es ja sowas ähnliches wie JAXB auch für CVS (oder du kannst statt CSV XML verwenden), dann gibt's die "Übersetzung" sogar gratis.



Also seht ihr da keine Probleme, was die Anzahl der Objekte angeht?


----------



## Fant (17. Aug 2012)

Hiermit kannst du auch direkt SQL-Querys auf deine csv-Datei schmeißen 
CsvJdbc Home


----------



## andreT (17. Aug 2012)

Ist das nur eine Spielwiese, oder hat das Programm langfristigen produktiven Character z.B. für eine Firma o.ä.? 
Wenn es eine Spielwiese ist würde ich das ganze von CSV nach XML portieren und dann z.B. diese API hier benutzen : XStream - Two Minute Tutorial
Die finde ich ganz schick und passt ja auch zu deinen Anwendungsfällen.
Wenn das ganze professionell sein soll, solltest du m.E. immer eine Datenbank benutzen. Für den Einstieg bzw. solltest du dich damit noch nicht auskennen, empfehle ich z.B. die Installation von xampp : apache friends - xampp 
Installation der DB ist da inclusive und das Ganze ist sehr einsteigerfreundlich. Dann hast du eine MySQL Datenbank in die du die Daten problemlos aus der CSV Datei direkt importieren kannst. Der Zugriff auf die Daten bzw. Lesen/Schreiben ist kinderleicht und weil der MySQl Zugriff auch via Java so verbreitet ist gibts dazu im Netz viele gute Tutorials!


----------



## maki (17. Aug 2012)

GerhardSchröder hat gesagt.:


> Also seht ihr da keine Probleme, was die Anzahl der Objekte angeht?


Nö, nicht im geringsten.

Ansonsten ist es vollkommen normal in OOP Sprachen mit Objekten zu arbeiten, ist sozusagen der Normalfall


----------



## GerhardSchröder (17. Aug 2012)

Fant hat gesagt.:


> Hiermit kannst du auch direkt SQL-Querys auf deine csv-Datei schmeißen
> CsvJdbc Home



Sieht interessant aus.



andreT hat gesagt.:


> Ist das nur eine Spielwiese, oder hat das Programm langfristigen produktiven Character z.B. für eine Firma o.ä.?



Kurz zu meiner Motivation.
Es handelt sich dabei nicht um ein langfristiges Projekt was professionell eingesetzt wird. Ist also eher eine Spielwiese. Trotzdem möchte ich den Entwurf einigermaßen flexibel halten, damit man ich Projekt vielleicht später einmal wieder rauskramen und erweitern kann, um sich dann vielleicht in eine neue Technologie o.ä. einzuarbeiten.
Ich möchte jetzt bei diesem Projekt etwas mit Git, Maven, JUnit und log4j experimentieren.


----------



## Mujahiddin (17. Aug 2012)

Also wenn du nur Adressen hast, und diese mit gar nichts anderem im Zusammenhang stehen, fände ich eine Datenbank zu viel. (eventuell embedded db)
Wenn die Menge der Adressen klein ist, dann würde ich 4 Listen empfehlen, die bei Programmstart einmalig eingelesen werden. Also "List<String> PLZ;" oder noch besser eine Klasse Address mit den 4 Attributen und eine 
	
	
	
	





```
List<Address>
```
...
Falls du enorm viele Daten hast, würde ich einen Scanner empfehlen, der als Delimiter ";" entgegennimmt. Du würdest dann alle Informationen zu einer Adresse zwischenspeichern und die übergebene Straße auf Gleichheit überprüfen.


```
private static final String searchAddressIn(File file, String street) throws FileNotFoundException {
	String plz = "";
	String str = "";
	String town = "";
	String borough = "";
	try( Scanner sc = new Scanner( new FileInputStream(file) ) ) {
		sc.useDelimiter( ";" );
		boolean match = false;
		while( !match ) {
			plz = sc.next();
			str = sc.next();
			town = sc.next();
			borough = sc.next();
			match = str.equals/*IgnoreCase*/( street );
		}
	} catch(NoSuchElementException e) { /* Scanner reached end */
		return null;
	}
	return plz + ";" + str + ";" + town + ";" + borough;
}
```


----------



## andreT (17. Aug 2012)

maki hat gesagt.:


> Nö, nicht im geringsten.
> Ansonsten ist es vollkommen normal in OOP Sprachen mit Objekten zu arbeiten, ist sozusagen der Normalfall


Das sehe ich auch so. Wenn die Daten mehr oder weniger bzw. ohnehin nur als Datenpool dienen um irgendwann mal weitere Technologien auszutesten, würde ich sogar einfach die Objekte serialisiert (vllt. in einer Liste oder einzeln) in eine datei speichern. Ich habe aktuell auch solch einen Datenpool indem ich aktuell ca. 2500 ähnliche Objekte *+* 2500 Objekte mit jeweils *~300(!) String Variablen* halte. Alles kein Problem, weder beim Einlesen noch beim Schreiben o.ä.. Ich hatte da auch erst Bedenken, bin jetzt aber froh von Anfangs CSV auf das serialisierte Speichern gewechslt zu haben. CSV bzw. die APIs dazu waren mir dann doch irgendwie zu ... stolperfallenmäßig (encoding, quoten, s.o.!).


----------



## ARadauer (17. Aug 2012)

Datenstruktur für 800 Datensätze? Liste ;-)
Bei 800.000 kannst du dir über irgendwelche Baumstrukturen für performates Suchen gedanken machen...


----------



## Mujahiddin (17. Aug 2012)

ARadauer hat gesagt.:


> Datenstruktur für 800 Datensätze? Liste ;-)
> Bei 800.000 kannst du dir über irgendwelche Baumstrukturen für performates Suchen gedanken machen...



Ich denke das Problem liegt z.T. darin, dass es sich um mehrere MB große Daten handeln soll. Naja heutzutage gibt's viel RAM also kann man notfalls auch mal 50MB in den Speicher laden (ob das so ne gute Idee ist...) aber ansonsten würde ich die Scanner-Methode empfehlen.

Wo mir was dazu einfällt: Gibt es ne besondere Struktur bei CSV, die den Anfang eines neuen Datensatzes signalisiert? Also z.B. zwei Semikolon. Dann könnte man die Datensätze intern einmal sortieren (natürlich auch abhängig davon, wie oft eine Straße abgefragt wird) und ein RAF verwenden, welches binär sucht.


----------



## hüteüberhüte (18. Aug 2012)

Ich würde auch Objekte erstellen und diese serialisieren. Als Datenstruktur würde ich eine Liste wählen. Zum Suchen würde ich die Liste durchgehen. Wenn die Suche nach einem Attribut zu langsam ist, würde ich dafür eine HashMap erstellen.

Btw: Sind die Datensätze geheim oder kannst du uns als Beispiel ein paar nennen, damit wir damit testen können?


----------



## vanny (18. Aug 2012)

So lange deine Datensätze nicht mehr beinhalten als  Postleitzahl;Straße;Stadt;Ortsteil,
und du unter 1Mio Einträge bleibst, kann man das Einlesen der kompletten CSV wohl verkraften.
Natürlich wäre es eleganter eine richtige DB zu verwenden. Dort sehe ich aber das Problem, dass du redundante imports aus deiner csv nur sehr schwer verhindern kannst, es sei denn jeder Eintrag kommt nur einmal vor oder die vorgehaltene CSV ist demensprechend frei von alten Datensätzen. Ist aber nur geraten, da ich nicht wirklich weiss, welchen Werdegang deine Daten so durchlaufen.

Zum Datentyp:
Schreib dir einen DatenTyp Adresse und leg diesen in eine List<Adresse>.

Gruß Vanny


----------



## GerhardSchröder (20. Aug 2012)

Hallo zusammen,

nachdem nun einige von Euch geschrieben haben, dass ich einen Datentypen Adresse bauen soll und ihn in einer einfachen Liste speichern soll, bin ich zu der Überzeugung gekommen, dass dies der "richtige" Weg ist.
Dies war ja auch eine meiner ersten Überlegungen.

Möchte mich noch einmal bei allen für Ihre Tipps und Kommentare bedanken.

Viele Grüße


----------



## hüteüberhüte (20. Aug 2012)

"Danke"-Button?


----------

