Lấy cảm hứng từ câu trả lời của GETah, tôi đã quyết định viết một cái gì đó tương tự cho chính mình với một số cải tiến:
- Lớp đang triển khai
Map<K,V>
-Giao diện
- Tính hai chiều thực sự được đảm bảo bằng cách quan tâm đến nó khi thay đổi giá trị bằng a
put
(ít nhất tôi hy vọng sẽ đảm bảo điều đó bằng cách này)
Cách sử dụng cũng giống như bản đồ bình thường, để xem ngược lại cuộc gọi ánh xạ getReverseView()
. Nội dung không được sao chép, chỉ một lượt xem được trả về.
Tôi không chắc rằng điều này là hoàn toàn chống lại sự đánh lừa (thực ra, có thể là không), vì vậy hãy bình luận nếu bạn nhận thấy bất kỳ sai sót nào và tôi sẽ cập nhật câu trả lời.
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;
}
}
}