Referenzen HashMap -> HashMap

Fulk

Mitglied
Hi,

ich habe folgendes problem:

Es gibt zwei HashMaps, bei der in der einen HashMap(realMap) für jeden Eintrag zum einen ein key und zum anderen ein String-Objekt drin stecken.

Die zweite HashMap(refMap) besitzt auch pro Element ein key und das value hingegen soll eine Referenz auf das value in der anderen HashMap sein.

Irgendwie habe ich gerade Tomaten auf den Augen und komm nicht weiter.

Code:
HashMap realMap = new HashMap();
HashMap refMap = new HashMap();
		
String object01 = "erstesObject";
String object02 = "zweitesObject";

realMap.put("realMapKey01", object01);
realMap.put("realMapKey02", object02);

refMap.put("refMapKey01", realMap.get("realMapKey01"));
refMap.put("refMapKey02", realMap.get("realMapKey02"));
		
System.out.println("-->"+refMap.get("refMapKey01"));
System.out.println("-->"+realMap.get("realMapKey01"));
System.out.println("-->"+refMap.get("refMapKey02"));
realMap.remove("realMapKey01");
System.out.println("-->"+realMap.get("realMapKey01"));
System.out.println("-->"+refMap.get("refMapKey01"));

Zuerst werden die HashMaps erstellt, dann die String-Objekte. Dann einfügen in die realMap und Einfügen der Referenz der realMap.

Zum Schluss wollte ich es mal testen und lasse mir das Ergebnis ausgeben:

Code:
-->erstesObject
-->erstesObject
-->zweitesObject
-->null
-->erstesObject

Mmm, warum ist in der 4. Zeile kein null ? Ich habe doch das String-Objekt aus der realMap gelöscht? Damit dürfte es doch garnicht mehr in der refMap existieren?

Danke für Eure Antworten!
 
Mmm, warum ist in der 4. Zeile kein null? Ich habe doch das String-Objekt aus der realMap gelöscht? Damit dürfte es doch garnicht mehr in der refMap existieren?
Du hast eine Referenz auf das Objekt entfernt, jedoch hat der Reference-Counter noch einen Zeiger auf die Referenz in der refMap. Wenn du ein Objekt in einen Container packst, übergibst und speicherst du im Prinzip lediglich eine Referenz auf ein Objekt im Speicher. Der Garbage Collector löscht erst dann ein Objekt (oder merkt die Löschung vor), wenn der Referenzzähler dieses Objekts Null wird.

Behelfen kannst du dir mittels Observer / Listener und Events. Du musst dann beispielsweise die remove-Methode von realMap überschreiben, und ein Event mit dem entsprechend zu löschenden Schlüssel werfen. Vorher meldest du die refMap als Zuhörer oder Beobachter an, und so kann deine refMap bei einem auftauchenden Event ebenfalls die entsprechende remove-Methode aufrufen.
 
Es gibt keine Referenz auf einen Wert in einer HashMap. Wenn du ein get auf einer HashMap machst kriegst du für den gegebenen Key den Original-Wert wieder raus und dieser hat dann nichts mehr mit der Map zu tun.

Was hast du denn eigentlich vor?
 
Danke erstmal für Eure Antworten,

ich möchte folgendes realisieren.

Ich habe eine HashMap für Objekte (realMap).

Dazu soll es noch eine weitere Map geben, die sozusagen eine andere "View" auf die realMap darstellt.

Mit View ist folgendes gemeint:

Originalobjekt: Artikel
View:
-key=findeArtikelMit_Id ; value=ref(Artikel)
-key=findeArtikelMit_Name ; value=ref(Artikel)

==> also mehrere unterschiedliche Keys zeigen auf ein und das selbe Objekt, ohne dieses Objekt mehrmals speichern zu müssen.

Was soll das?
HashMap, weil schneller Zugriff, da key bekannt ist
View, weil ich mehrere Zugriffmöglichkeiten(keys) für ein Objekt brauche

Kann mir jemand helfen?

Danke!
 
Das ist ja auch in Ordnung so.

Damit deine Maps aber konsistent sind solltest du einfach noch ein Objekt drumrum machen:

Java:
public class ArticleManager {

     private final Map<String,Article> idToArticle = new HashMap<String,Article>();
     private final Map<String,Article> nameToArticle = new HashMap<String,Article>();

    public void addArticle(Article article){
          idToArticle.put(article.getID(),article);
          nameToArticle.put(article.getName(),article);
    }

    public void removeArticle(Article article){
        idToArticle.remove(article.getID());
        nameToArticle.remove(article.getName());
    }

    public Article getArticleByID(String id){
        return idToArticle.get(id);
    }

    public Article getArticleByName(String name){
       return nameToArticle.get(name);
   }

}

So werden die Maps immer auf dem selben Stand gehalten und du abstrahierst davon das es intern überhaupt Maps gibt. Du könntest also entsprechend auch in einer Datenbank speichern wenn das irgendwann mal nötig würde.
 
Ja,

es ist ein Objekt drumherum, nämlich die Klasse "Cache" :)

Aber bei Deiner Lösung ist doch das Problem, dass es zwei Maps gibt, in denen das gleiche Objekt drin ist.

Bei wenigen Objekten ist dies OK, aber wie sieht es bei komplexen Objekten aus, von denen es wiederum mehrere Tausend(E-Commerce-Anwendung) geben kann? Da habe ich quasi doppelten Speicherbedarf.

Genau das wollte ich umgehen.

Trotzdem Danke für Dein Listing!

edit:
Idee ist wie gesagt, dass es einen Cache(HashMap) gibt, der alle Objekte hält. Darüber hinaus soll es aber noch andere Maps geben, die für verschiedene Views zuständig sind.

Ein Beispiel hatte ich oben schon genannt(findByID, ... Name, ...). Ein anderes wäre eine Map, die zur Ersetzung behilflich ist.
 
Zuletzt bearbeitet:
Bei wenigen Objekten ist dies OK, aber wie sieht es bei komplexen Objekten aus, von denen es wiederum mehrere Tausend(E-Commerce-Anwendung) geben kann? Da habe ich quasi doppelten Speicherbedarf.
In Java wird bei nicht-primitiven Datentypen (nicht int, boolean, char, byte, etc) eine Referenz verwendet, und keine Kopie, wie du dir das vorstellst. deshalb sind deine Bedenken in dieser Richtung unberechtigt.
Die Objekte liegen irgendwo im Speicher, und es werden lediglich Referenzen auf diese übergeben und gespeichert - Das ist der große Vorteil an Java, dass man sich um Speicherverwaltung relativ wenig Sorgen machen muss (in den meisten Fällen).
 
Ahh,

na klar - ich Pflaume!

Also beim Reinlegen in die Maps kann ich ruhig jeweils das Objekt übergeben, reingelegt wird ja sowieso nur eine Referenz.

Na klar, jeder Bezeichner bei einem Objekt ist ja quasi eine Referenz auf eine Speicherstelle. Und diesen Bezeichner kann ich ja überall hinlegen wo ich will.(Einmal in Map01 und dann in Map02 --> beide Maps referenzieren dann auf Speicherstelle xyz).

:)

Danke.
 

Neue Beiträge

Zurück