Collections Liste mit festem Index

  • Themenstarter Themenstarter Gonzo17
  • Beginndatum Beginndatum
G

Gonzo17

Gast
Hey,

eigentlich klingt die Frage für mich selbst so banal, dass ich es zu den Grundlagen zählen würde, aber ich kann die Frage einfach nicht beantworten.

Was ich möchte ist eine Liste, deren Indizes sich nicht ändern. Füge ich drei Objekte der Liste hinzu, sollen diese IMMER den Index behalten, den sie am Anfang bekommen. Lösche ich Element zwei aus der Liste, dann sollen die anderen beiden Elemente trotzdem ihre Indizes behalten. Ein neu hinzugefügtes Element kann dann gerne an den freien Platz gesetzt werden.

Nunja, die Frage ist, ob es so eine Liste gibt und ob das überhaupt Sinn macht. Oder muss man das selbst über ein Array machen? Kann ja theoretisch ein Array der größe 100 angeben, das eben das beschriebene Verhalten umsetzt und falls es voll sein sollte wird ein größeres Array erzeugt und die Einträge kopiert.

Ob das Sinn macht frage ich mich gerade im Bezug auf das Iterieren über die Liste. Vielleicht fehlt mir da die genaue "Definition der Liste". Aber wenn es eine Liste gibt, die sich so verhält wie ich es beschreibe, dann würde man beim drüberiterieren ja durchaus mal auch null bekommen.

Gruß,
Gonzo


PS: Ich glaube ich habe so eine ähnliche Frage schonmal gestellt. Die Antwort damals war wohl, dass ich eine Map benutzen soll. Aber eigentlich will ich ja eben eine Liste und keine Map, denn mit der Map hab ich wiederrum andere Aufgaben zu erledigen und da wird das Leben nicht einfacher.
 
Mhm, den Sinn sehe ich jetzt nicht da drin, aber mit der ArrayList sollte das gehen, die kann
Code:
"null"
Elemente aufnehmen, zusammen mit der List-Methode set(int index, E element)) sollte dann doch deine Anforderung umsetzbar sein oder nicht?
 
Nunja. Ich möchte ja eigentlich nur "adden" und mich nicht selbst um den Index kümmern. Würde ich es direkt setzen über den Index, könnte ich auch eine Map nehmen. Ich will aber lediglich ein Element hinzufügen, bekomme den Index returned und will mich drauf verlassen können, dass der Index sich nicht ändert.

Wie gesagt, ich weiß nicht ob eine Liste so eine Anforderung überhaupt erfüllen soll. Aber deswegen frag ich ja nach. 🙂
 
Nunja. Ich möchte ja eigentlich nur "adden" und mich nicht selbst um den Index kümmern. Würde ich es direkt setzen über den Index, könnte ich auch eine Map nehmen. Ich will aber lediglich ein Element hinzufügen, bekomme den Index returned und will mich drauf verlassen können, dass der Index sich nicht ändert.

Wie gesagt, ich weiß nicht ob eine Liste so eine Anforderung überhaupt erfüllen soll. Aber deswegen frag ich ja nach. 🙂


du könntest die Methoden überschreiben,.. 😀
 
Zuletzt bearbeitet:
Tut mir Leid, aber Java hat leider keinen fertigen 3D-Egoshooter in den Libs mitgeliefert. 🙁

…

So, jetzt noch mal ernster: Wo ist denn das Problem, wenn du dir selbst eine passende Abstraktionsschicht erstellst? Momentan schließe ich mich eRaaaa an (null benutzen). Wenn du dein Modellierungsproblem etwas genauer/umfassender darstellst, kann man dir eventuell bessere Hinweise geben.

Ark
 
Tut mir Leid, aber Java hat leider keinen fertigen 3D-Egoshooter in den Libs mitgeliefert. 🙁

Danke, auf Sarkamus kann ich verzichten. 😉


So, jetzt noch mal ernster: Wo ist denn das Problem, wenn du dir selbst eine passende Abstraktionsschicht erstellst?

Da gibt's kein Problem. Das könnte ich auch tun. Ich wollte ja lediglich wissen, ob es schon etwas gibt, das genau diese Funktionalität erfüllt. Man muss das Rad ja nicht neu erfinden. Listen tun es anscheinend nicht. Maps tun es auch nicht, da ich einen Key generieren müsste. Arrays tun es nicht, weil man die eben selbst befüllen muss. Und da ich die Weisheit nicht mit Löffeln gefuttert habe und meine Recherchen & Tests nichts ergaben, habe ich eben gedacht, dass ich mal im Forum frage.


Wenn du dein Modellierungsproblem etwas genauer/umfassender darstellst, kann man dir eventuell bessere Hinweise geben.

Ok, dann nochmal im Detail.
Ich möchte Objekte "verwalten" (in einer Liste oder was auch immer). Wenn ich ein neues Objekt hinzufüge, dann bekomme ich eine ID zurückgegeben, die eindeutig ist und sich NIEMALS ändert. Ich möchte über dieses Verwaltungsobjekt ohne große Probleme iterieren können (keine Prüfung auf null). Wird ein Objekt gelöscht, ist die ID meinetwegen "freigegeben" (oder vielleicht auch nicht, das ist eigentlich nicht wichtig), auf jeden Fall dürfen sich dadurch keine IDs ändern (zB durch ein "nachrücken" der Elemente in der Liste).

Zu Listen: Hier werden anscheinend immer Elemente nachgerückt (zumindest hat bisher niemand etwas anderes gesagt) und somit ändert sich die ID. Verwendet man null an den entsprechenden Stellen, wird das Iterieren umständlich, man muss eben dran denken auf null zu prüfen.

Zu Maps: Hier müsste ich den Key selbst generieren. Ist auch wieder Mehraufwand. Beim Iterieren über die Map würde ich auch wieder erst ein Set der Keys benötigen.

Zu Arrays: Hier muss man eben alles selbst machen. Und beim Iterieren über das Array per Index kann man eben auch auf null stoßen.


Versteht mich nicht falsch. Es ist ja nicht so, dass ich das Problem nicht lösen konnte oder es mir zu viel wäre eine Map zu benutzen. Es ist eher eine theoretische Frage, wie man das am einfachsten, elegantesten oder performantesten lösen könnte. Und ich dachte eben, dass es vielleicht schon ein Konstrukt gibt, das genau das macht. Aber es hat den Anschein, als wäre das nicht der Fall. 🙂
 
warum verwaltest du die IDs nicht unabhaengig davon wie und wo die elemente gespeichert werden ?

lass es mich anders formulieren: Verwalte diese eindeutige ID nicht als irgendeine Eigenschaft von deiner "Speicherung".
 
Schließe mich bygones an: Wenn es sich wirklich um IDs handelt, dann gehören die zum Objekt selbst, und zwar explizit (und nicht implizit, wie es bei der Liste der Fall wäre).

Spricht was gegen eine statische Zählervariable?

Java:
public class Foo{

    private static int nextID;

    private final int id;

    public Foo(){
        id = nextID++;
    }

    public int getID(){
        return id;
    }
}
Ark
 
Klingt vernünftig. Dann könnte ich wiederrum doch eine Map benutzen um hab die Keys dafür schon parat. Danke für die Anregungen. 🙂
 
Bist du dir sicher, dass du da eine Map brauchst? Wenn du [c]equals()[/c] und [c]hashCode()[/c] überschreibst bzw. [c]Comparable.compareTo()[/c] implementierst, könnte/sollte auch ein Set genügen.

BTW: Bei Multihreading musst du meinen Code entsprechend anpassen; das gibt sonst böse Überraschungen. 😉

Ark
 
Klingt auch interessant, danke. Brauchen tu ich eine Map nicht, nur dann, wenn sie mir hilft. 😉
 
Brauchen tu ich eine Map nicht, nur dann, wenn sie mir hilft. 😉
Wenn du sie nicht brauchst, hilft sie nicht. ^^ (Eher das Gegenteil: eigentlich einfache Sachen werden saukompliziert, wenn man Krücken verwendet, obwohl man normal gehen kann.)

Ein wesentlicher Unterschied zwischen [c]Map<Integer, Foo>[/c] und [c]Set<Foo>[/c] ist übrigens, dass in letzterem Foo-Objekte nur einmalig vorkommen ("einmalig" laut [c]equals()[/c]). Falls du dir diesbezüglich nicht sicher bist, solltest du dein Problem genauer durchdenken.

Ark
 
(Eher das Gegenteil: eigentlich einfache Sachen werden saukompliziert, wenn man Krücken verwendet, obwohl man normal gehen kann.)

Das war ja auch ein Grund, weshalb ich gefragt habe. Neue Wege erschliessen, die eleganter sind und vor allem auch einfacher wartbar.

Ein wesentlicher Unterschied zwischen [c]Map<Integer, Foo>[/c] und [c]Set<Foo>[/c] ist übrigens, dass in letzterem Foo-Objekte nur einmalig vorkommen ("einmalig" laut [c]equals()[/c]). Falls du dir diesbezüglich nicht sicher bist, solltest du dein Problem genauer durchdenken.

Das könnte man ja alleine schon durch die ID sicherstellen, wenn man die ID so wie du vorgeschlagen hast erstellt und in der equals-Methode auf die ID prüft.
 
Okay, mal ganz anders gefragt: Brauchst du die ID so überhaupt? Ich meine, die Objektreferenz selbst ist doch eigentlich auch eine Art ID, allerdings mit dem Unterschied, dass man sie sich nicht direkt anzeigen lassen kann (auch wenn [c]System.identityHashCode()[/c] eine Annäherung sein könnte/sollte; verlassen würde ich mich auf diese Methode also nicht).

Sofern du also die ID nicht anzeigen musst (als Zahl oder sonstwas), sollten die Referenzen eigentlich reichen, um zu sagen: Das hier ist dieses Objekt, es ist nicht jenes Objekt.

EDIT: Okay, ein weiterer möglicher Verwendungszweck für "eigene" IDs, wie sie in meinem Code vergeben werden: Logische Uhr ? Wikipedia (Spätestens da musst du synchronisieren. Oder du verwendest [c]java.util.concurrent.atomic.AtomicInteger[/c].)

Ark
 
Zuletzt bearbeitet:
Also die ID möchte ich vor allem, weil es einen Netzwerkmodus geben soll und ich in diesem Netzwerkmodus nicht immer ganze Objekte über die Leitung geben möchte. Einmalig muss das Objekt zum Server, aber dann sollte es reichen, die Aktionen per ID zu übergeben. Objekt1 auf Client1 macht Aktion A, da werden dann einfache Codes verschickt gepaart mit der ID. Vielleicht handelt es sich hier um Datenmengen, die (noch) vernachlässigbar sind. Aber sobald sie es nicht sind, habe ich trotzdem ein Konstrukt, das eben mit geringen Datenmengen auskommt. 🙂 So zumindest der Plan.
 
Verstehe. Achte dann aber darauf, dass du die global gültige ID vom Server vergeben lässt, sonst steht die ID 42 bei einem Client für einen Blumentopf und bei einem anderen Client für einen Zimmerschlüssel. 😉 Außerdem musst du dem Server mitteilen, welche IDs wieder frei geworden sind, damit sie wiederverwendet werden können.

Ark
 

Neue Themen


Zurück
Oben