ich bin grad dabei mir ein kleines Verwaltungstool für Pflanzen zu schreiben. Dabei besitzt eine Pflanze neben anderen Attributen auch eine eindeutige Id. Diese wird standardmäßig über einen autoincrement gesetzt. Da die Pflanzen aber bereits nummeriert sind, brauche auch die Möglichkeit die Id manuell zu setzen. Dabei sollen natürlich trotzdem keine Ids mehrfach vergeben werden. Wie prüfe ich am besten, ob eine Id bereits vergeben ist (Zeile 17-19)?
Unter php würde ich dafür einfach ein statisches assoziatives Array mit key=Id nutzen. Wie kann man sowas unter JAVA realisieren?
Java:
publicclassPlantimplementsSerializable{privatestaticAtomicInteger nextId =newAtomicInteger();privateint id;publicPlant(){this.id = nextId.incrementAndGet();}publicintgetId(){return id;}publicvoidsetId(int id){if( id >= nextId.get()){
nextId.set(id);}else{// if ( id existiert ? ){// throw new Exception("id still exists")// }}this.id = id;}}
Das assoziative Array heist in Java [JAPI]Map[/JAPI] und wird üblicher Weise durch eine [JAPI]HashMap[/JAPI] representiert. Aber achtung, die enthält die Daten unsortiert. Wenn Du die Map sortiert (nach Schlüssel) durchgehen möchtest brauchst Du eine [JAPI]TreeMap[/JAPI]. (Frag mich bitte nicht, warum die TreeMap heist...) Unabhängig davon welche Implementierung du wählst sollte der Typ der Variablen
Danke erstmal für die Hinweise. In diese Richtungen habe auch schon experementiert.
Eine Map <Integer,Plant> kann ich nicht verwenden, da ich ja bereits im Konstruktor ein add/put mit this durchführen müsste. Wäre ja super, da ich dann nicht noch zusätzlich eine Collection von Plants bräuchte.
Ich benutze nun ein HashSet<Integer>. Daß Einträge überschrieben werden macht ja nichts, da hier ja nur festgehalten wird welche IDs vergeben sind. Da müssen also sowieso keine doppelten Einträge stehen.
@Spin
wenn man Doppelte vermeiden will ist absolut ein Set geeigneter,
auch dort ruft man natürlich vorher contains() auf oder schaut sich den Rückgabewert von add() an,
die Liste bietet keinen Vorteil, ist nur langsamer
es ist zwar nicht ganz zu empfehlen, technisch aber normal möglich, im Konstruktor schon das Plant-Objekt in eine Map einzufügen,
auch wenn der Konstruktor danach noch mit Exception abgebrochen wird und der Aufrufer das Plant-Objekt vielleicht nicht erhält,
in der Map wäre es so normal wie jedes andere eingefügt/ verfügbar, vielleicht nicht komplett mit Werten befüllt
@Timothy Truckle
das war ja am Anfang auch so, aber noch manuell zugewiesene Ids erwünscht
Die Id soll persistent sein. Nach Speichern und Laden, sollen die IDs wieder die selben sein. Diese können Lücken enthalten
Der bestehende Pflanzenbestand hat bereits Ids bzw. Nummern, die bereits Lücken enthalten (hier und da mal was gestorben).
Wenn erstmal alle Pflanzen erfasst sind und neue hinzukommen, kann der autoincrement greifen.
Die Id soll persistent sein. Nach Speichern und Laden, sollen die IDs wieder die selben sein. Diese können Lücken enthalten
Der bestehende Pflanzenbestand hat bereits Ids bzw. Nummern, die bereits Lücken enthalten (hier und da mal was gestorben).
Wenn erstmal alle Pflanzen erfasst sind und neue hinzukommen, kann der autoincrement greifen.
D.h.: Du brauchst die höchste ID ehr selten.
Dann würde ich die Anwendung auch nicht darauf optimieren, sondern die Liste der Pflanzen dann, wenn die neue ID gebraucht wird nach der ID
sortieren (mit Comparator) um die aktuell höchste zu ermitteln.
@Timothy Truckle
Ja ich denke das werde ich auch so machen (müssen?):
Ich hab nämlich ein Problem beim Laden/Speichern. Ich verwende ein Objekt "PlantManagerProject", welches u.a. in einer ArrayList<Plant> die Pflanzen hält. Wenn im laufenden Program nun ein Projekt Speichere und ein neues Lade müsste ich immer nextID beim starten eines neuen Projekts/Laden eines Vorhandenen immer wieder auf auf 0 zurücksetzen und die Liste vergebenerIDs zurücksetzen....
Das kommt mir ziemlich unsinnig vor.
Performance spielt hier ja ohnehin keine große Rolle.