Я не уверен, что понимаю вопрос, но думаю, что вам нужно несколько способов сопоставления различных уникальных ключей со значениями и соответствующей очистки при исчезновении значения.
Я вижу, что вы не хотите бросать свои собственные, но есть достаточно простая композиция карты и мультикарты (я использовал мультикарту Guava ниже, но Apache тоже должен работать), чтобы делать то, что вы хотите. У меня есть быстрое и грязное решение ниже (пропущенные конструкторы, так как это зависит от того, какую карту / мультикарту вы хотите использовать):
package edu.cap10.common.collect;
import java.util.Collection;
import java.util.Map;
import com.google.common.collect.ForwardingMap;
import com.google.common.collect.Multimap;
public class MIndexLookupMap<T> extends ForwardingMap<Object,T>{
Map<Object,T> delegate;
Multimap<T,Object> reverse;
@Override protected Map<Object, T> delegate() { return delegate; }
@Override public void clear() {
delegate.clear();
reverse.clear();
}
@Override public boolean containsValue(Object value) { return reverse.containsKey(value); }
@Override public T put(Object key, T value) {
if (containsKey(key) && !get(key).equals(value)) reverse.remove(get(key), key);
reverse.put(value, key);
return delegate.put(key, value);
}
@Override public void putAll(Map<? extends Object, ? extends T> m) {
for (Entry<? extends Object,? extends T> e : m.entrySet()) put(e.getKey(),e.getValue());
}
public T remove(Object key) {
T result = delegate.remove(key);
reverse.remove(result, key);
return result;
}
public void removeValue(T value) {
for (Object key : reverse.removeAll(value)) delegate.remove(key);
}
public Collection<T> values() {
return reverse.keySet();
}
}
удаление - это O (количество ключей), но все остальное в том же порядке, что и типичная реализация карты (некоторое дополнительное постоянное масштабирование, так как вы также должны добавлять вещи к обратному).
Я только что использовал Object
ключи (должно быть в порядке с соответствующими реализациями equals()
и hashCode()
и различием ключей) - но вы могли бы также иметь более конкретный тип ключа.