Wert bei Objekterzeugung verändern

JuriW

Aktives Mitglied
Guten Abend zusammen!
Ich habe eine Idee, aber leider keine Ahnung, wie ich die umsetzen soll.

Angenommen ich habe eine LinkedList<Kunde> kundenkartei, mit Kunden, jeder Kunde hat verschiedene Attribute (Name, Vorname, Kundennummer) und eine Verwaltung, die Kunden der Liste hinzufügt, und löscht.

Gibt es eine Möglichkeit, dass ich die Kundennummer pro neuerzeugten Kunden um 1 erhöhe?

Das heißt, sobald der Kunde erstellt wird, wird diesem eine neue Kundennummer zugewiesen?Soweit ich mich erinnere existiert der Kunde, wenn ich "Kunde k1 = new Kunde ("Meier", "Hans", 1);" schreibe noch nicht, sondern erst wenn etwas damit passiert, zum Beispiel wenn ich ihn in eine Liste einfüge. Wie teil ich das dem Konstruktor mit, dass er beim nächsten Kunden die Kundennummer um 1 erhöhen soll?

Macht das überhaupt Sinn? Macht eine Liste überhaupt Sinn, oder kann man das eleganter mit einer Map lösen, da eine Map ja einen Key hat?

Vielen Dank und liebe Grüße
 
MMn kannst du ruhig eine List verwenden.

Wenn jeder Kunde automatisch eine ID erhalten soll könntest du das über eine statische Variable in der Klasse Kunde regeln die um 1 erhöht wird wenn der Konstruktor aufgerufen wird.
Java:
class Kunde {
    private static int ID_COUNTER = 1;
    private int id;
    private String name;
   
    public Kunde(String name) {
        this.id = ID_COUNTER++;
        this.name = name;
    }
}

Du könntest natürlich auch die neue ID anhand der List-Länge berechnen. new Kunde(name, (kunden.size() + 1))
 
Soweit ich mich erinnere existiert der Kunde, wenn ich "Kunde k1 = new Kunde ("Meier", "Hans", 1);" schreibe noch nicht, sondern erst wenn etwas damit passiert, zum Beispiel wenn ich ihn in eine Liste einfüge.
Nein, bei new wird das Objekt erzeugt. (oder beziehst du dich da auf Compiler-Untiefen?)

Eine andere Möglichkeit wäre Benutzung des Fabrik-Patterns, finde ich persönlich schöner.

Wenn man schon die statische Variante nimmt, bieten sich das AtomicInteger bzw AtomicLong an, damit wird's dann auch Threadsafe 😉
 
Okay, vielen Dank für die Aufklärung, dann hab ich wohl irgendwas verwechselt.

Also die Lösung von Robat hat mir schon sehr geholfen, es funktioniert so ohne Probleme, Danke dir nochmal!

einen neuen Kunden erzeuge ich nun so

Code:
int kdID = 0;
verwaltung.kdHinzufügen("Rühl", "Roswitha", kdID);
verwaltung.kdHinzufügen("Zufall", "Rainer", kdID);
//...bliebig viele Kunden

Und es wird pro Kunde immer um 1 inkrementiert, so wie es sich gehört.

Das einzige was mich stört ist eventuell, dass ich int kdID = 0; davor geschrieben habe, da er mir sonst einen Compilerfehler gibt, dass die Variable nicht existiert. Gibt es eine Möglichkeit das eleganter zu lösen?
 
Warum gibt es den Parameter kdID denn überhaupt? Der ist doch sowieso immer 0.

BTW:
Der Beitrag von mir oben ist nur Beispielhaft.
Generell würde ich auf davon @mrBrown erwähnte Factory-Pattern zurückgreifen um sowas zu realisieren.
 
Warum nicht? Die kdID gehört doch zum Kunden dazu, oder hab ich einen Denkfehler?

Ich hab leider keine Ahnung was das Fabrik-Pattern sein soll, werds mir aber sofort mal durchlesen.
 
Doch sie gehört dazu.
Wenn du es aber mit einer statischen Variable umgesetzt hast kannst du den Parameter auch weglassen weil ja in der Kunden-Klasse dann sowieso sowas steht wie this.id = staticIdCounter++
 
einen neuen Kunden erzeuge ich nun so

Code:
int kdID = 0;
verwaltung.kdHinzufügen("Rühl", "Roswitha", kdID);
verwaltung.kdHinzufügen("Zufall", "Rainer", kdID);
//...bliebig viele Kunden

Und es wird pro Kunde immer um 1 inkrementiert, so wie es sich gehört.

Das einzige was mich stört ist eventuell, dass ich int kdID = 0; davor geschrieben habe, da er mir sonst einen Compilerfehler gibt, dass die Variable nicht existiert. Gibt es eine Möglichkeit das eleganter zu lösen?
In diesem Fall bekommen alle Kunden die ID 1 (oder 0, je nachdem ob pre oder post-inkrement).
Damit das funktioniert, musst du entweder den Zähler gänzlich außerhalb der Kunden-Klasse behandeln, oder gänzlich innerhalb, so wie von @Robat gezeigt.
 
Doch sie gehört dazu.
Wenn du es aber mit einer statischen Variable umgesetzt hast kannst du den Parameter auch weglassen weil ja in der Kunden-Klasse dann sowieso sowas steht wie this.id = staticIdCounter++

Leider nicht, oder ich hab was übersehen.
Vielleicht sollte ich noch erwähnen, dass meine main-methode in der Verwaltungsklasse ist?

In diesem Fall bekommen alle Kunden die ID 1 (oder 0, je nachdem ob pre oder post-inkrement).
Damit das funktioniert, musst du entweder den Zähler gänzlich außerhalb der Kunden-Klasse behandeln, oder gänzlich innerhalb, so wie von @Robat gezeigt.

Also es funktioniert gerade so wie ich will, der Zähler ist in der Attributliste von Kunde und statisch. Nur, dass ich, wie gesagt, in der main-methode auch nochmal
Code:
int kdID = 0;
schreiben muss, damit es funktioniert.
 
Wie sieht deine Klasse aus?
An zwei Stellen die Variable mit dem gleichen Namen deklarieren ist in diesem Fall alles andere als richtig oder nötig...
 
Also die Verwaltungsklasse mit Main sieht so aus
Code:
import java.util.LinkedList;

public class Vermietung {

    private static LinkedList<Kunde> kunden = new LinkedList<Kunde>();

    public void kdHinzufügen(String vorname, String nachname, int kdID) {

        kunden.add(new Kunde(vorname, nachname, kdID));
    }

    public static void main(String[] args) {

        int kdID = 0;
        Vermietung verwaltung = new Vermietung();

        verwaltung.kdHinzufügen("Fritz", "Egon", kdID);
        verwaltung.kdHinzufügen("Roswitha", "Rühl", kdID);
        verwaltung.kdHinzufügen("Rainer", "Zufall", kdID);

        System.out.println("Liste aller Kunden: ");
        for (Kunde kunde : kunden) {
            System.out.println(kunde);
        }
    }
}

Und die Kundenklasse so:

Code:
public class Kunde {
   
    private String vorname;
    private String nachname;
    private int kdID;
    private static int ID_COUNTER = 1;   
    public Kunde(String vorname, String nachname,  int kdID) {
        this.vorname = vorname;
        this.nachname = nachname;
        this.kdID =ID_COUNTER++;
    }
   
    public String toString() {
 
        return  "KundenID: " + kdID + " Vorname: "   + vorname + " Nachname " + nachname;
    }
}

Der Output sieht so aus

Code:
Liste aller Kunden:
KundenID: 1 Vorname: Fritz Nachname Egon
KundenID: 2 Vorname: Roswitha Nachname Rühl
KundenID: 3 Vorname: Rainer Nachname Zufall

Ich hab den Code stark gekürzt, damit man sich auf das Wesen meiner Frage (die id) beschränken kann.
Und so klappts auch. Wie gesagt, nur das int kdID = 0; ist irgendwie nicht so schön.
 
Schau dir mal genau den Konstruktor von Kunde an.
Dir sollte auffallen, dass du nur mit dem Attribut kdID arbeitest .. das lokale Feld kdID benutzt du nicht.
Es würde an der Funktionalität nichts ändern, wenn du den kdID Parameter aus dem Konstruktor raus nimmst. (natürlich dann dem entsprechend auch die Aufrufe anpassen.)
 
Ah, nun hab ichs verstanden.

Ich habe jetzt die kdID aus der Parameterliste des Konstruktors, und aus dem Funktionsaufruf genommen und die ID wird trotzdem angezeigt. Und ich muss davor kein int kdID = 0; mehr schreiben

Vielen Dank für eure Hilfe!
 

Zurück
Oben