Java Kurze Frage zu GregorianCalendar

flopalko

Ensign
Registriert
Sep. 2010
Beiträge
197
Hallo liebe CBler,

habe da eine kleine Frage zu GregorianCalendar.
Es handelt sich um folgenden Quelltext:

Code:
GregorianCalendar beginn = new GregorianCalendar(2011, 4, 20);

GregorianCalendar ende = new GregorianCalendar(2011, 4, 26);

methode(eigene klasse, eigene klasse, beginn, ende);

beginn.set(2012, 1, 18);

ende.set(2011, 1, 24);

methode(eigene klasse, eigene klasse, beginn, ende);

Die Methode trägt diese Attribute (es gibt eine Klasse, die all diese als Variable hat) in einen Vector dieser Klasse ein. Mein Problem ist, dass mir beim ersten Aufruf der Methode auch das Datum, das ich erst danach sette eingetragen wird. Gibt es da ieine elegante Möglichkeit dies zu lösen oder soll ich einfach statt beginn und ende zu erschaffen als Argument in die Methode immer new Gregorian... schreiben?

Vielen Dank im Voraus für jede Hilfe.
lg flopalko
 
Das liegt an Call by Reference, oder in anderen Worten, ja du brauchst new Gregorian.. nochmal.

Code:
methode(eigene klasse, eigene klasse, new GregorianCalendar(2011, 4, 20), new GregorianCalendar(2011, 4, 26));
methode(eigene klasse, eigene klasse, new GregorianCalendar(2012, 1, 18), new GregorianCalendar(2012, 1, 24));
 
Zuletzt bearbeitet:
so also die methode sieht wie folgt aus:

Code:
public Ferienhaus ferienhausBuchen(Kunde kun, Kategorie kat, GregorianCalendar beginn, GregorianCalendar ende){

		for(Ferienhaus f:ferienhaeuser) {
 //einem Ferienhaus ist eine Kategorie zugeordnet, man bucht für eine kategorie(ja ist nicht realitätsnahe aber angegeben)
			if (kat == f.getKategorie() && f.checkAvailability(beginn, ende)) {

				f.addBuchung(new Buchung(kun, f, beginn, ende));
 //f ist ein Vector vom Typ Ferienhaus
				return f;

			}

		}

		return null;

	}

aber gut die erste frage hat meine Frage eh schon beantwortet...

Gibt es da eine elegantere Möglichkeit das so zu machen, ohne new Gregor... in die methode zu schreiben?
Weiters habe ich noch eine Frage:

Code:
GregorianCalender cal1 = new GregorianCalendar(jahr, monat, tag);
GregorianCalendar cal2 = new GregorianCalendar();
cal2 = cal1;
cal2.add(Calendar.DAY_OF_MONTH, 7

Dadurch ändere ich auch den Tag bei cal1. Muss ich das mit der Methode clone(); machen?

lg
 
flopalko schrieb:
so also die methode sieht wie folgt aus:
Gibt es da eine elegantere Möglichkeit das so zu machen, ohne new Gregor... in die methode zu schreiben?
Nein, eigentlich nicht. Ich frage mich nur, warum du dich so dagegen sträubst? 4 verschiedene Datumsangaben, 4 verschiedene Objekte. Wie im echten Leben ist das in der OOP ;)

Der einzige Grund, warum man Objekte wiederverwenden könnte, sind Performancegründe. Aber das spielt bei dir keine Rolle und ist semantisch auch unschön. Ich hatte zum Beispiel man einen kleinen Shooter programmiert in 2D. Die verschossenen Raketen waren alles neue Objekte, kein Ding. Bei der Minigun mit ein paar tausend Schuss pro Minute hingegen wurde es dann kritisch, also habe ich die "verschossenen" Kugeln in einem Pool gesammelt und wieder neu abgeschossen.

flopalko schrieb:
Weiters habe ich noch eine Frage:

Code:
GregorianCalender cal1 = new GregorianCalendar(jahr, monat, tag);
GregorianCalendar cal2 = new GregorianCalendar();
cal2 = cal1;
cal2.add(Calendar.DAY_OF_MONTH, 7

Dadurch ändere ich auch den Tag bei cal1. Muss ich das mit der Methode clone(); machen?

lg

Da hast du genau den selben Effekt wie oben, ich würde dir das mal zum lesen empfehlen:

http://www.iks.hs-merseburg.de/~usc...03_006.htm#mj4375f35ed5e61c4d8120182955b44e1f

Du änderst bei deinem Code nicht AUCH den Tag 1, sondern du änderst NUR den Tag 1. Die Referenz auf Tag 2 ist verloren, da kommst du dann nicht mehr dran.
 
Zuletzt bearbeitet:
Ah ok. Danke für die Erklärung.
In unserer Vorlesung ist dies leider nicht behandelt worden, von C hab ich eh Ahnung.
 
Nun würde ich noch gerne den Konstruktor von Buchung sehen ^^
Sieht für mich wie ein typisches Problem aus, bei dem die Handhabung von Pointern missverstanden wird.
 
Code:
public Buchung(Kunde kunde, Ferienhaus ferienhaus, GregorianCalendar beginn, GregorianCalendar ende){

		this.kunde = kunde;

		this.ferienhaus = ferienhaus;

		this.beginn = beginn;

		this.ende = ende;

	}

Dabei ist klar dass ende in Buchung auf das gleiche Objekt wie ende in der main-Methode zeigt. Wenn ich daher nachträglich etwas daran ändere ändere ich auch den Calendar von Buchung.
Gut durch Überlegung wirds klar. Dankeschön.

Schreibe ich allerdings:
this.beginn = (GregorianCalendar)beginn.clone();
das gleiche für ende

Dann sollt es ja funktionieren oder?
 
Statt clone kannst du dann auch gleich new benutzen, ist um einiges sauberer.
 
Gut habs jetzt so gelöst: (ich nehm an so hast dus gemeint)

Code:
public Buchung(Kunde kunde, Ferienhaus ferienhaus, GregorianCalendar beginn, GregorianCalendar ende){
		this.kunde = kunde;
		this.ferienhaus = ferienhaus;
		this.beginn = new GregorianCalendar();
		this.beginn.setTime(beginn.getTime());
		this.ende = new GregorianCalendar();
		this.ende.setTime(ende.getTime());
	}

Ich hätte nur noch gerne eine Erklärung warum dies eleganter als mit clone() ist.
Wär nett wenn du mir das noch beantwortest.
 
Das ist die umständliche Version :) Du kannst im Konstruktor schon direkt zuweisen wie vorher auch, aber von außen neue Objekte einbringen wäre besser, siehe dazu die aller erste Antwort ganz oben.

Ich kann schon nachvollziehen, was dich an dieser Dynamik stört. Wenn du aber eine Zeit lang mit objekt-orientierten Sprachen gearbeitet hast (das ist nicht nur in Java so ;) ) wirst du feststellen, dass das Verhalten verdammt gut ist wie es ist, auch wenn man manchmal kurz nachdenken muss. Kurz gesagt: das Verhalten aus deinem ersten Post ist völlig in Ordnung. Denn wenn du wirklich 4 unterschiedliche Datumsangaben machen willst, dann brauchst du nun mal 4 Objekte dazu. Wenn sich nun ein Objekt ändert, dann wirkt sich das eben auf die Buchung aus. Und wenn du das nicht willst, dann musst du dafür sorgen, dass die Datumsobjekte von außen eben nicht mehr verändert werden.

Bei skalaren Typen wie int, float etc. verhält sich das übrigens nicht so (sondern genau so wie von dir oben angenommen), deswegen solltest du dir nochmal den Unterschied zwischen skalaren Typen und Referenztypen anschauen.

Clone sollte generell eher vermieden werden. Es gibt zwar Situationen, in denen Clone die beste und sauberste Lösung darstellt, aber wenn man nicht explizit in diese Region vordringt, dann braucht man es zu 99,9% nicht. Clone ist jetzt nicht "böse" wie viele andere Programmkonstrukte, aber es geht so gut wie immer ohne und ist dann auch intuitiver. Clone kopiert z.B. nur "Flach" - d.h. alle Unterobjekte in deinem Objekt sind immernoch die alten.
 
Zuletzt bearbeitet:
Danke für alle Antworten.
Ich habs jetzt wieder in die ursprüngliche Form geändert. Relevant war dies sowieso nur für die Methode generiereTestdaten(), die wie der Name ja zeigt nichts mit dem Programm zu tun hat.
Da hab ich jetzt einfach alle 3 Buchungen mit dem gleichen Datum gemacht.
Danke für all die Erklärungen nur ich bin halt von C gewohnt mit möglichst wenigen Variablen auszukommen und nicht aus Jux und Tollerei neue zu erschaffen.
edit: dies gilt dann für objektorientierte Sprachen auch für Instanzen von Klassen (für mich)
Scheinbar sollte ich mich davon aber lösen.
 

Ähnliche Themen

Zurück
Oben