# In ArrayList Daten verändern



## kuzdu (23. Mai 2012)

Hallo,

ich arbeite gerade an einer Adressverwaltung. Die Adresse wird in einer Arraylist gespeichert und der Anwender soll die Möglichkeit haben einzelne Daten aus seiner Adresse zu verändern.

Die Daten werden so gespeichert:



```
String Adresse = "Vorname"+ " " +"Nachname"+ " " +"Straße"+ " " +"PLZ"+ " " +"ORT"+ "eindeutige ID";
		
AdressListe.add(Adresse);
```

Im Internet finde ich nur immer Codebeispiele wo der String in der ArrayList nur ein "Wort" enthält. Ein einzelnes Wort zu ändern ist einfach. Aber in meinem String sind ja gleich 5 verschiedene Daten. Wenn ich also z.B. nur meinen Nachnamen ändern möchte, soll der Rest bestehen bleiben und nicht explizit vom User erneut eingegeben werden müssen.

Ich suche den Datensatz, der verändert werden soll per indexOf:


```
for (int i = 0; i <AdressListe.size(); i++) {
	    
String name = (String)AdressListe.get(i);

if(name.indexOf("eindeutige ID") >= 0) {
	    		
	    		//Hier Veränderung von nur ausgewählten Daten (z.B. nur Nachnamen verändern) 


	    	}
}
```

Geht mein Vorhaben überhaupt auf meine Art und Weise?
Welche wäre eine einfacherer bzw. bessere Möglichkeit mein Problem zu lösen?

Im Internet habe ich nichts brauchbares gefunden, bzw. nicht die Möglichkeit wie man einen "komplexen" String verändert.


Gruß

PS: Falls was unklar ist, einfach melden bitte 

PPS: Oder muss ich mit dem String (name) arbeiten und Trennzeichen setzen oder so etwas in der Art?


----------



## nillehammer (23. Mai 2012)

Der bessere Weg wäre, eine Klasse Adresse zu implementieren, die alle Strings enthält, etwa so:

```
public class Adresse {

   private String name;
  
   public String getName() {
     return this.name;
   }

   public void setName(final String name) {
    this.name = name;
  }

   //... alle weiteren Strings entsrpechend
}
```
Dann kannst Du über die Setter die Werte ändern, die Du möchtest. Für die Ausgabe des Gesamtstrings implementierst Du am besten eine eigene Methode, die Du dann aufrufst.

P.S. Und die Liste darf auch gern Generics benutzen, also so:

```
List<Adresse> adressListe = new ArrayList<Adresse>();
//... hier die ganzen Adressen adden.
Adresse erste = adressListe.get(0);
```
Wie Du siehst, sparst Du Dir damit den Cast.

P.P.S Klassennamen sollten mit Großbuchstaben beginnen, Variablennamen mit Kleinbuchstaben.


----------



## AquaBall (23. Mai 2012)

Deine Art die Daten zu "speichern" in dem du einen String zusammenhängst, ist so ziemlich die katastrophalste Vorgangsweise die man sich vorstellen kann!!!

Wenn das dein Ernst ist, dann ist das vermutlich dein aller-erster Kontakt mit Datenstrukturen!
Du machst genau das Gegenteil, von dem was Programme erreichen wollen: STRUKTUR und gezielten Zufgriff auf Information, (statt alles in eine Topf zu werfen und kräftig umrühren.)

Leg das Programm nochmal weg, und lies dich in classen und Datenstrukturen ein.
Und beschäftige dich mal mit der Frage "Was ist eine Informationseinheit"?

Grob gesagt: Alles was einen eigene Bezeichnung hat ist eine eigenen Einheit: (Vorname, Nachname, Straße, Postleitzahl ...)
*Da gehört jedes in eine eigene Variable!
*Vorzugsweise in eine Klasse Adresse, die all dies eVariablen als Eigenschaft beinhaltet.
Später in eine Datenbank, die MUSST du so strukturieren.

Nicht ohne Grund bestehen in den meisten Beispielen 
	
	
	
	





```
ArrayList aus nur ein "Wort"
```
. Weil das *EINE *Informationseinheit ist!


----------



## 2AndAHalfBit (24. Mai 2012)

AquaBall hat gesagt.:


> Grob gesagt: Alles was einen eigene Bezeichnung hat ist eine eigenen Einheit: (Vorname, Nachname, Straße, Postleitzahl ...)
> *Da gehört jedes in eine eigene Variable!
> *Vorzugsweise in eine Klasse Adresse, die all dies eVariablen als Eigenschaft beinhaltet.
> Später in eine Datenbank, die MUSST du so strukturieren.



Das mit dem Muss ist ein Gerücht, ich kenne Firmen die geben nix auf Normalisierung und einen String in einer DB speichern, das geht auch....

Nein, mal im Ernst. Aqua hat schon recht, Deine Softwarearchitektur ist in dem Fall nicht ideal gewählt. 
Du solltest in der Tat eine Klasse erstellen, die Deine Daten hält (z.B. Addresse) und Objekte dieser Klasse in deine Arraylist einfügen. Soweit ich weiss speichert eine ArrayList nur Referenzen, Du kannst Dir also die Referenz aus der Liste holen und über getter/setter in Deiner Klasse Addresse die alle Attribute neu setzen wie Du willst. 

Das hat darüber hinaus den Vorteil, dass Du Dir keine Syntax für Deinen String überlegen musst und macht Dein Programm besser anpassbar. 

Jetzt zu Deinem Problem: Ich weiß nicht genau wie eine ArrayList reagiert, aber ich vermute mal, dass das Problem sein wird, das Strings immutable sind. Das beudetet, dass sie nicht verändert werden können. Initialisierst Du einen String, und änderst ihn dann, entsteht ein neuer String und dieser neue String ist ein neues Objekt auf einem neuen Speicher (= eine neue Referenz). An der Stelle weiss ich aber nicht, wie die Arraylist darauf reagieren wird. Kann ich aber heute abend mal ausprobieren...


----------



## kuzdu (24. Mai 2012)

@nillehammer: Vielen Dank hat geklappt.
@AquaBall: Wenn ich deinen Beitrag lese, komme ich mir echt(!) dumm vor  Aber recht hast. Bin wieder etwas klüger und lern ja noch 

Falls irgendwelche anderen Leute hier mal drüber stolpern, hier ist meine jetzige Lösuung, ist zwar noch etwas roh, sollte es allerdings wohl tun:


```
//In der Hauptklasse

ArrayList<String> adressList = new ArrayList<String>();
			
			Adresse a = new Adresse();   //Zugriff auf Klasse Adresse
			
			a.setName("buh");
			a.setNachname("guh");
			
			
			
			
			adressList.add(a.toString());
			
		
			System.out.println(adressList.get(0));
			
			a.setName("neu");
			
			  adressList.set(0, a.toString());
		
			
			System.out.println(adressList.get(0));

-----------------------------------------------------------
//Klassse Adresse


public class Adresse {


	private String name;
	private String nachname;
	private String all;
	


	public void setName(String name) {
		this.name = name;
	}
	
	public void setNachname(String nachname) {
		this.nachname = nachname;
	}
	
	public String getName() {
		return this.name;
	}
	
	public String getNachname() {
		return this.nachname;
	}
	
	
	public String toString() {
	return this.all = name + " " + nachname;
	}
	
}
```


----------



## AquaBall (24. Mai 2012)

kuzdu hat gesagt.:


> @nillehammer: Vielen Dank hat geklappt.
> @AquaBall: Wenn ich deinen Beitrag lese, komme ich mir echt(!) dumm vor  Aber recht hast. Bin wieder etwas klüger und lern ja noch



Dumm würd ich nie sagen zu einem Anfänger. Das Gefühl brauchts du dir nicht geben!
Dazu ist ja das Anfängerforum auch da!
Dumm ist erst, wenn man aus angeboter Hilfe nicht lernen will.

Du hast ja den ersten wesentlichen Schritt schon geschafft!
Jetzt machst du noch den 2., dann bist du bei 'Klassen'  angekommen:
Dein 
	
	
	
	





```
ArrayList
```
 soll natürlich keien 
	
	
	
	





```
Strings
```
 beinhalten, da wärst du nämlcih ähnlich weit wie gestern, sondern soll 
	
	
	
	





```
Adressen
```
 verwalten. Also


```
//In der Hauptklasse
ArrayList<Adresse> adressList = new ArrayList<Adresse>();		// !!!
			
			Adresse a = new Adresse();   //Zugriff auf Klasse Adresse
			
			a.setName("buh");
			a.setNachname("guh");
			adressList.add(a);		// !!! Nicht String!
// Der SInn ist: eben KEINEN String daraus machen, sondern Daten "im Original" lassen, 
// und nur für Ausgaben "menschen-gerecht" in einen String aufbereiten:
			System.out.println(adressList.get(0).toString());
			
			a.setName("neu");
			 adressList.set(0, a);		// !!! Nicht String
			System.out.println(adressList.get(0).toString());

-----------------------------------------------------------
//Klassse Adresse

public class Adresse { 		// Das schaut schon recht profesionell aus, gratuliere!

	private String name;
	private String nachname;
// --	private String all;		// Unnötig, und wegen Speicher, Redundanz, ... nicht sinnvoll.

	public void setName(String name) { this.name = name; }
	public void setNachname(String nachname) { this.nachname = nachname; }

	public String getName() { return this.name; }
	public String getNachname() { return this.nachname; }
	
	@Override			// ... zu Klarheit
	public String toString() {
		return name + " " + nachname;
	}
}
```


----------



## kuzdu (24. Mai 2012)

Achso! Ja, wunderbar.

Besten Dank!


----------



## nillehammer (24. Mai 2012)

[JAVA=14]
adressList.set(0, a);      // !!! Nicht String
[/code]
Das Kommando ist überflüssig. Mit der Variable _a_ hat man noch die Referenz auf die Adresse, die auch in der Liste gespeichert ist. D.h. die Änderung gilt auch für die in der Liste gespeicherte Adresse. Es handelt sich dabei nämlich um das selbe (im Sinne von identische) Objekt. Man braucht die veränderte Adresse nicht nochmal an die selbe Stelle zu speichern.


----------



## AquaBall (24. Mai 2012)

nillehammer hat gesagt.:


> [JAVA=14]
> adressList.set(0, a);      // !!! Nicht String
> [/code]
> Das Kommando ist überflüssig. Mit der Variable _a_ hat man noch die Referenz auf die Adresse, die auch in der Liste gespeichert ist. D.h. die Änderung gilt auch für die in der Liste gespeicherte Adresse. Es handelt sich dabei nämlich um das selbe (im Sinne von identische) Objekt. Man braucht die veränderte Adresse nicht nochmal an die selbe Stelle zu speichern.



Hast du natürlich absolut recht!
Mag TO auch nun evtl verwirren, dass er mit

```
a.setName("neu");
```
schon den Wert im ArrayList verändert, (Weil's ja keine Liste VON Objekten ist, sondern eine Liste AUF REFERENZEN von Objekten.)

Ist also nur nötig/gerechtfertigt, wenn das Objekt a gegen das Objekt b ersetzt werden soll.


```
Adresse a = new Adresse();
a.setName("buh");
a.setNachname("guh");
adressList.add(a);
System.out.println(adressList.get(0).toString());

a.setName("new");
System.out.println(adressList.get(0).toString());      // !!! Bereits Ausgabe der neuen Daten!

Adresse b = new Adresse();
b.setName("foo");
b.setName("bar");
adressList.set(0, b);      // !!! Objekt komplett ersetzt!
```


----------

