PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Java-Problem


Gast
2008-05-22, 10:11:28
Moin !

Ich muss gerade ein kleines Projekt realisieren und hab ein Problem, weil ich bisher mit Jave nix am Hut hatte.
In einem Vector befinden sich mehrere Objekte, die unter anderem einen eindeutigen Namen besitzen. Nun sollen in den Vector neue Objekte eingefügt werden, was ja auch kein Problem ist. Ich möchte aber, dass bei der Erstellung bzw. dem Versuch, das neue Objekt in den Vector einzufügen geprüft wird, ob der Name des neuen Objekts schon vergeben ist, sprich schon ein Objekt mit dem Namen im Vector existiert.
Dazu gibt es bestimmt eine fertige Methode, nur find ich die gerade nicht :)

Monger
2008-05-22, 10:24:39
Zuerst einmal: Vector ist veraltet und nicht in allen Situationen sehr performant, du solltest stattdessen eine ArrayList nehmen.


Und dann ist mein spontaner Eindruck, dass vermutlich auch die ArrayList gar nicht das ist was du willst. Du brauchst etwas, wo jedes Element garantiert nur einmal vorkommt - dafür ist ein Set (http://java.sun.com/javase/6/docs/api/java/util/Set.html) gut. Es gibt verschiedene Implementierungen eines Sets: HashSet, SortedSet... je nachdem was du halt für Anforderungen hast.

Das Problem mit ArrayLists ist, dass eine Suche darin umso länger dauert, je größer die ArrayList wird. Für jedes neue Element was du versuchst einzufügen, dauert das ganze also länger und länger. Je nachdem wie oft du das machst, kann ein aufbauen einer solchen Liste schonmal ein paar Minuten dauern. Ein Set merkt sich die Hashes, und sucht beim einfügen erstmal nach dem richtigen Hash Bucket - das geht rasend schnell, und zwar relativ unabhängig davon, wieviele Elemente darin sind.

Damit das Set weiß, welche Elemente gleich sind und welche nicht, musst du sowohl hashCode() als auch equals() richtig implementieren - was du ja aber ohnehin für jede eigene Klasse tun solltest.

darph
2008-05-22, 10:26:37
Vectors sind meines Wissens deprecated. Wenn du ein Objekt über einen Namen (String oder ein anderes Objekt) identifizieren willst, bietet sich eine HashMap an.

Monger
2008-05-22, 10:43:04
Wenn du ein Objekt über einen Namen (String oder ein anderes Objekt) identifizieren willst, bietet sich eine HashMap an.

Okay, ist in dem Fall wahrscheinlich die deutlich unkompliziertere Lösung! :ugly:

Ectoplasma
2008-05-22, 10:48:10
Map objects = new HashMap();
// or
// Map objects = new TreeMap();

objects.put("first", new MyObject());
if (objects.contains("first")) {
// already contained
} else {
// not contained
}

anderer Gast
2008-05-22, 10:54:24
zu HashSet, SortedSet:

Kann man darin auch auf Elemente direkt mit einem Index zugreifen?
Ich nutze meistens eine ArrayList, weil ich selber weiss, dass ein gerade benötigtes Objekt an Position x in der ArrayListe zu finden ist, d.h. ich muss nicht erst nach etwas suchen.

Ich muss zugeben, dass ich mich etwas mit den Collection-Ausprägungen schwer tue, was ich für welchen Zweck einsetzen sollte. Meistens läufts, wie gesagt, auf eine ArrayList hinaus, weil ich damit umzugehen weiss. :/

Ectoplasma
2008-05-22, 11:37:01
zu HashSet, SortedSet:

Kann man darin auch auf Elemente direkt mit einem Index zugreifen?
/

Nein kann man nicht, es sei denn der Index selbst ist ein Schlüsselement. Mathematisch betrachtet hat ein Set keine Ordnung. Durch eine geeignete Implementierung z.B. einem TreeSet, kann man eine Ordnung herbeiführen.

Von einer Indizierung ist ausser bei Vectoren oder einer ArrayList sowieso abzuraten, da diese sehr inperformant sein kann. Vorallem bei verketteten Listen kann das Laufzeitverhalten quadratisch sein.

Monger
2008-05-22, 11:37:33
Nein, du kannst nicht über den Index zugreifen. Ganz einfach, weil ein Set keinen Index in dem Sinne hat - die Objekte liegen weder geordnet hintereinander noch lückenlos.

Sind halt zwei völlig verschiedene Anwendungsgebiete. Die meisten kennen halt nur die Arrays, und gehen davon aus dass alles andere auch ähnlich geordnet im Speicher liegen muss.

Immer dann wenn die Reihenfolge eine entscheidende Rolle spielt, sind die List Implementierungen die richtige Wahl (von denen es ja nun auch einige interessante Varianten gibt, wie z.B. LinkedList), immer dann wenn die Reihenfolge keine besondere Rolle spielt, sind Maps und Sets einen Blick wert.

instinct
2008-05-22, 13:47:43
Man kann sich bei HashMap/Set aber eine Keyliste holen und über diese iterieren.
Aber so nebenbei gesagt, Maps/Sets sind auch nicht zum Iterieren gedacht, der Vorteil liegt im Zugriff auf einzelne Elemente ohne großen Suchaufwand.

Monger
2008-05-22, 14:12:28
Klar kannst du über ein Set/Keyset iterieren - macht ja auch vielfach Sinn, wenn man z.B. auf allen Objekten eine bestimmte Methode aufrufen will - aber diese Iteration hat eben keine festgelegte Reihenfolge, und folgerichtig auch keinen Index.


Der Index ist ja nunmal auch relativ selten eine wirklich wichtige Information. Nicht umsonst verbirgt die For-Each Schleife ihn völlig.

Ectoplasma
2008-05-22, 14:40:24
Man kann sich bei HashMap/Set aber eine Keyliste holen und über diese iterieren.
Aber so nebenbei gesagt, Maps/Sets sind auch nicht zum Iterieren gedacht, der Vorteil liegt im Zugriff auf einzelne Elemente ohne großen Suchaufwand.

Selbstverständlich sind diese "auch" zum Iterieren gedacht. Iteratoren bieten für jede Collection die höchst mögliche Performance und vorallem sind Iteratoren generisch, was generischen Code ermöglicht der keine Rücksicht auf die Implementierung nehmen muss.

Indizierung ist etwas ganz anderes als eine Iteration.