2013-08-09 10 views
13

Was ich suche:Java Generics erzwingen gleichen Typs für Schlüssel und Werte der Karte

Ich suche etwas zu konstruieren, die sowohl die Schlüssel und Werte eines Kartentyp auf erzwingt: wie Map<Key<X>, Value<X>> Art . Allerdings möchte ich zusätzlich erzwingen, dass die Typen übereinstimmen innerhalb jeden Schlüssel/Wert-Eintrag, aber zwischen Einträge, kein Typ muss erzwungen werden.

zum Beispiel innerhalb der gleichen Karte, diese Schlüssel/Wert-Paare sollten als gültig betrachtet werden:

  • Key<Integer> Karten Value<Integer>
  • Key<String> Karten Value<String>
  • Key<Double> Karten Value<Double>

Aber etwas wie dieses wäre ungültig:

  • Key<Integer> Mapping Value<String>
  • Key<Double> Mapping Value<Boolean>

Wie kann ich dies mit Java Generika erreichen?


Was ich nicht bin auf der Suche nach:

  • Ich verstehe, dass ich so etwas wie Set<Pair> implementieren kann, wo Paar Schlüssel/Wert des gleichen Typs akzeptiert. Wenn Sie jedoch nach suchen, ist der Schlüssel keine konstante Zeitoperation mehr.

  • Ich verstehe, dass ich etwas wie Map<Key<?>, Value<?>> tun konnte und nur behaupten, dass der Schlüssel und der Wert zur Laufzeit derselbe Typ sind. Allerdings habe ich mich gefragt, ob dies möglich ist streng mit Generika.

+0

Haben Sie diese Map nicht in einer generischen Klasse? –

+0

Nicht unbedingt. Nur um eine 'Map' zu erstellen, die nur" erzwingt ". Die Schlüssel müssen vom gleichen Typ sein wie die Werte (oder haben den gleichen generischen Typ in ihnen, im Falle von' Schlüssel '/' Wert '), aber Jedes Schlüssel/Wert-Paar kann von einem anderen Typ sein. " –

Antwort

17

Sie können dies tun, aber Sie haben Ihren eigenen Wrapper auf einem Map rollen:

class MyTypeSafeMap { 
    private Map<Key<?>, Value<?>> map; 
    public <T> void put(Key<T> key, Value<T> value) { 
    map.put(key, value); 
    } 

    public <T> Value<T> get(Key<T> key) { 
    return (Value) map.get(key); 
    // we know it's safe, but the compiler can't prove it 
    } 
} 

Vergleichen z.B. Guavas ClassToInstanceMap.

+0

Macht es einen Unterschied, ob ich den Rückgabewert an (Value) oder (Value ) umwandle? –