Inspiriert von GETah's answer Ich beschloss, etwas ähnliches von mir mit einigen Verbesserungen zu schreiben:
- Die Klasse setzt die
Map<K,V>
-Interface
- Die Bidirektionalität wirklich durch die Pflege gewährleistet ist, wenn ein Wert zu ändern durch ein
put
(zumindest hoffe ich es zu garantieren hiermit)
Usage wie eine normale Karte ist, einen umgekehrten Blick auf die Zuordnung Aufruf zu erhalten getReverseView()
. Der Inhalt wird nicht kopiert, es wird nur eine Ansicht zurückgegeben.
Ich bin mir nicht sicher, ob dies völlig narrensicher ist (eigentlich ist es wahrscheinlich nicht), so zögern Sie nicht, zu kommentieren, wenn Sie irgendwelche Fehler bemerken, und ich werde die Antwort aktualisieren.
public class BidirectionalMap<Key, Value> implements Map<Key, Value> {
private final Map<Key, Value> map;
private final Map<Value, Key> revMap;
public BidirectionalMap() {
this(16, 0.75f);
}
public BidirectionalMap(int initialCapacity) {
this(initialCapacity, 0.75f);
}
public BidirectionalMap(int initialCapacity, float loadFactor) {
this.map = new HashMap<>(initialCapacity, loadFactor);
this.revMap = new HashMap<>(initialCapacity, loadFactor);
}
private BidirectionalMap(Map<Key, Value> map, Map<Value, Key> reverseMap) {
this.map = map;
this.revMap = reverseMap;
}
@Override
public void clear() {
map.clear();
revMap.clear();
}
@Override
public boolean containsKey(Object key) {
return map.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
return revMap.containsKey(value);
}
@Override
public Set<java.util.Map.Entry<Key, Value>> entrySet() {
return Collections.unmodifiableSet(map.entrySet());
}
@Override
public boolean isEmpty() {
return map.isEmpty();
}
@Override
public Set<Key> keySet() {
return Collections.unmodifiableSet(map.keySet());
}
@Override
public void putAll(Map<? extends Key, ? extends Value> m) {
m.entrySet().forEach(e -> put(e.getKey(), e.getValue()));
}
@Override
public int size() {
return map.size();
}
@Override
public Collection<Value> values() {
return Collections.unmodifiableCollection(map.values());
}
@Override
public Value get(Object key) {
return map.get(key);
}
@Override
public Value put(Key key, Value value) {
Value v = remove(key);
getReverseView().remove(value);
map.put(key, value);
revMap.put(value, key);
return v;
}
public Map<Value, Key> getReverseView() {
return new BidirectionalMap<>(revMap, map);
}
@Override
public Value remove(Object key) {
if (containsKey(key)) {
Value v = map.remove(key);
revMap.remove(v);
return v;
} else {
return null;
}
}
}
als Nicht-Mathematiker ich diese Art von Struktur nennen würde „eine Karte, was Sie Werte Nachschlag durch Schlüssel oder umgekehrt können“ –
Schade, dass es für Generika hat keine Unterstützung, scheint Guava tut. –
https://github.com/megamattron/collections-generic hat BidiMap mit Generics Unterstützung –