Data in arraylist wordt overschreven??

Status
Niet open voor verdere reacties.

DcMatic

Gebruiker
Lid geworden
10 okt 2013
Berichten
15
Hallo,

als opdracht moet ik een "briefwisseling" maken. Ik houd mijn brieven bij in een arraylist.

Ik heb hiervoor een abstracte klasse "ABrief", daaronder 2 abstracte klassen "Interne of externebrieven" en daaronder 4 concrete klassen
"interneUitnodiging, interneMedeling, externeMededeling, externePromotie".

Ik hou dan een arraylist bij van ABrief.

ik vraag de data op en maak een nieuwe brief, die ik daarna toevoeg aan mijn arraylist.

Als ik daarna nog een brief maak, wordt de data van mijn eerste brief overschreven.

Iemand enig idee hoe dit kan komen??

ik doe het volgende: (de volledige code heb ik toegevoegd in bijlage)

System.out.println("Wat is je naam?");
zender.setNaam(scan.next());

System.out.println("Wat is de naam van de ontvanger?");
ontvanger.setNaam(scan.next());

System.out.println("Geef de aanspreking in.");
aanspreking.setAanspreking(scan.next());

System.out.println("Geef de betreft in.");
betreft.setBetreft(scan.next());

System.out.println("Geef de content in.");
content.setContent(scan.next());

InterneUitnodiging brief = new InterneUitnodiging(zender,
ontvanger, aanspreking, betreft, content);
BrievenLijst.voegBriefToe(brief);

System.out.println(brief.getHoofding() + brief.toString()
+ brief.getSlot());
}

public static void voegBriefToe(ABrief brief) {
brievenLijst.add(brief);
}
 

Bijlagen

Het probleem is dat een object eigenlijk altijd een referentie naar het adres is waar het object zich in het geheugen bevindt (zie voor meer informatie bijvoorbeeld: http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.3.1) en jij voor het verwerken van alle gegevens telkens dezelfde objecten gebruikt. Op deze manier verwijzen alle brieven die je aanmaakt dus naar dezelfde objecten en hebben daardoor ook dezelfde waardes. Er zijn echt veel oplossingen denkbaar en elke oplossing kent weer zijn voor- en nadelen, dus je zult zelf de afweging moeten maken welke oplossing het beste bij je past. Maar hier zijn een paar mogelijke oplossingen:

1 -> De klassen die je momenteel gebruikt voor het samenstellen van een brief zijn heel eenvoudig met enkel een string als attribuut en daardoor kun je (zonder dat het gedrag van je applicatie wijzigt) ook gewoon de constructor aanroepen:

[cpp]
System.out.println("Wat is je naam?");
zender = new Persoon(scan.next());
// ...
[/cpp]

Maar zodra de klassen ook maar iets complexer worden is deze oplossing al niet meer bruikbaar.

2 -> De basisinformatie die je aan de gebruiker vraagt is voor alle brieven hetzelfde en dus een repeterende cyclus* in je code die makkelijk in (hulp)methodes ondergebracht kan worden:

[cpp]
public static Persoon getZender() {
System.out.println("Wat is je naam?");
return new Persoon(scan.next());
}

public static Persoon getOntvanger() {
System.out.println("Wat is de naam van de ontvanger?");
return new Persoon(scan.next());
}

public static Aanspreking getAanspreking() {
System.out.println("Geef de aanspreking in.");
return new Aanspreking(scan.next());
}

public static Betreft getBetreft() {
System.out.println("Geef de betreft in.");
return new Betreft(scan.next());
}

public static Content getContent() {
System.out.println("Geef de content in.");
return new Content(scan.next());
}

// ...
if (y == 1) {
zender = getZender();
ontvanger = getOntvanger();
aanspreking = getAanspreking();
betreft = getBetreft();
content = getContent();
InterneUitnodiging brief = new InterneUitnodiging(zender, ontvanger, aanspreking, betreft, content);
BrievenLijst.voegBriefToe(brief);

System.out.println(brief.getHoofding() + brief.toString() + brief.getSlot());
}
// ...
[/cpp]

*) Door de code in je huidig project op een iets slimmere manier te orderen is het geen repeterende cyclus meer:

[cpp]
if (y >= 1 && y <= 4) {
// ...
ABrief brief = null;

if (y == 1) brief = new InterneUitnodiging(zender, ontvanger, aanspreking, betreft, content);
else if (y == 2) brief = new ExterneUitnodiging(zender, ontvanger, aanspreking, betreft, content);
else if (y == 3) brief = new InterneMededeling(zender, ontvanger, aanspreking, betreft, content);
else if (y == 4) brief = new ExternePromotie(zender, ontvanger, aanspreking, betreft, content);

if (brief != null) {
BrievenLijst.voegBriefToe(brief);
System.out.println(brief); // door de toString methode in elke klasse te implementeren is het niet meer noodzakelijk om de output handmatig samen te stellen
// en kun je voor het tonen van alle brieven (y == 5) ook gewoon iets schrijven als: for (ABrief brief : BrievenLijst.leesBrieven()) System.out.println(brief)
}
}
[/cpp]


Het nadeel van deze oplossing is echter wel dat het niet gegarandeerd is dat de objecten uniek zullen zijn (indien er bijvoorbeeld toch een bestaand object wordt gebruikt). Verder geldt ook voor de objecten van een klasse die via een getter kunnen worden opgehaald dat er een object reference value wordt opgehaald en indien het een mutable object is eventuele wijzigingen dus ook gelden voor de klasse waarvan je de getter hebt opgehaald, en dat is niet altijd wenselijk (bijvoorbeeld in het geval van encapsulation).


3 -> Het toevoegen van een copy constructor (kan ook in combinatie met de tweede oplossing, maar dit geeft dan wel wat overhead):

[cpp]
public class Persoon {
// ...
public Persoon(Persoon p) {
naam = p.getNaam();
voornaam = p.getVoornaam();
}
}

// ...

public abstract class ABrief {
public ABrief(Persoon zender, Persoon ontvanger, Aanspreking aanspreking, Betreft betreft, Content content) {
this.zender = new Persoon(zender);
this.ontvanger = new Persoon(ontvanger);
this.aanspreking = new Aanspreking(aanspreking);
this.betreft = new Betreft(betreft);
this.content = new Content(content);
}

// ...

public Persoon getZender() {
return new Persoon(zender);
}
}
[/cpp]

Met deze oplossing is het gegarandeerd dat de objecten uniek zijn en is het ook mogelijk de objecten die via getters worden opgehaald af te schermen.

(ja ja, ik had wat tijd over :P)
 
uren heb ik hiernaar gezocht, maar als je het eens ziet is het wel logisch!!

Heeeeeeeeeeel erg bedankt voor de duidelijke uitleg!!!!

Laat ons hopen dat je in de toekomst nog veel tijd over hebt :d, er volgen namelijk nog opdrachten en hoogstwaarschijnlijk nog veel problemen....

Nogmaals hartelijk bedankt!!!!!!!
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan