2016-04-11 5 views
0

Derzeit implementiere ich die Multimap-Klasse, um Duplikate mit Multisets zu ermöglichen. Insbesondere arbeite ich an der boolean putAll(Multimap<? extends K, ? extends V> multimap) Methode.Guava: Ist es zulässig, eine Multimap auf allgemeine Supertypen zu übertragen?

Ich möchte, dies zu tun:

Map<K, Collection<V>> map = ((Multimap<K, V>)multimap).asMap(); 

wo asMap() würde normalerweise eine Map<? extends K, Collection<? extends V>> zurück.

Ist das gültig (wirft keine Fehler, vorausgesetzt, ich füge nicht zur Karte hinzu)? Wenn nicht, wie kann ich das beheben?

+1

Warum möchten Sie das tun? Das Argument für 'putAll' wird schreibgeschützt verwendet, also'? ausgedehnt "ist, was Sie wollen. –

+0

@PaulBoddington Ich möchte das 'asMap()' -Objekt daraus erhalten. Allerdings mache ich mir Sorgen, dass diese Methode eine ClassCastException auslösen würde, wenn ich diese Methode aufrufen und versuchen würde, eine 'Map > zu erhalten. Ich weiß aber nicht viel darüber und mein Gehirn brennt ein wenig. – aspaltv

+0

Sie erhalten keine 'ClassCastException', weil die Typen gelöscht werden. Sie können einfach 'Map > map = multimap.asMap(); '. –

Antwort

2

Nein, es ist nicht gültig, aus dem gleichen Grund, dass es nicht gültig ist, List<T> zu List<Object> zu werfen.

Multimap.asMap() gibt eine Ansicht zurück, according to the documentation. Dies bedeutet, dass

Multimap<K, V> multimap = ...; 
Map<SuperOfK, SuperOfV> map = (<some cast>) multimap.asMap(); 
map.put(superOfK, superOfV); 

Sollte die multimap aktualisieren. Während dies würde sich in einem ClassCastException führen nicht, etwas zu tun, wie die Schlüssel iterieren würde:

for (K key : multimap.keys()) { } 

Daher ist es nicht sicher geben, so zu werfen, so ist es verboten.

Natürlich haben Sie dieses Problem nicht, wenn Ihre Multimap unveränderlich ist - aber es ist im Allgemeinen der Grund, warum Sie nicht sollten. Und "Ich werde der Karte nicht hinzufügen" ist nicht gut genug für den Compiler - es weiß nicht, dass Sie das nicht tun werden.

+0

Ich plane nicht, die Multimap zu aktualisieren. Gibt es einen gültigen Weg, um das Map > -Objekt daraus zu erhalten. – aspaltv

+0

"Ich plane nicht zu aktualisieren" der Compiler weiß das nicht. Die einzige Möglichkeit besteht darin, die Daten explizit in eine neue Datenstruktur des richtigen Typs zu kopieren. –

+0

Okay, ich habe es verstanden. Ich mache nur eine anonyme Klasse, die eine Ansicht dieser Multimap ist. Danke für die Hilfe, Bruder! – aspaltv

2

Andere haben Ihre spezifische Frage behandelt, aber ich denke, dass Sie die falsche Frage stellen (und versuchen, etwas zu tun, was Sie nicht tun sollten).

Zuerst möchte ich fragen, warum Sie Multimap selbst implementieren. Es scheint wahrscheinlich, dass Sie dies vermeiden könnten.

Zweitens Sie versuchen map.putAll(Map) zu verwenden, um die asMap() Ansicht der Multimap bei der Umsetzung zu Ihrer Multimap.putAll(Multimap) weitergegeben hinzuzufügen. Dies ist fast sicher falsch und würde die Spezifikation von Multimap.putAll verletzen. Die Collection Werte in der asMap() Ansicht sind jeweils Live-Ansichten der Werte für den zugehörigen Schlüssel und deren Inhalt wird ändern, wenn das Multimap ändert. Wenn Sie diese Sammlungen direkt zu der Map hinzufügen, die Sie vermutlich Ihre Multimap Implementierung unterstützen, wird Ihre Multimap am Ende ändern, wenn die andere Multimap wird später geändert. Nicht nur das, aber was passiert, wenn Sie bereits Werte für diesen Schlüssel in Ihrem Map haben?

Verwandte Themen