我有同样的需求,想出了这个可能有用的 BiMap。它只使用一个 hashmap 并返回一个 entry 对象,以便可以为返回值提供特定类型并允许映射到 null。
public class BiMap<T1, T2>
{
public static class Entry<T1, T2>
{
public final T1 item1;
public final T2 item2;
public Entry( T1 item1, T2 item2 )
{
this.item1 = item1;
this.item2 = item2;
}
}
private final HashMap< Object, Entry<T1, T2> > mappings = new HashMap<>();
private int loopedLinkCount;
public void put( T1 item1, T2 item2 )
{
remove(item1);
remove(item2);
Entry<T1, T2> entry = new Entry<T1, T2>( item1, item2 );
mappings.put( item1, entry );
mappings.put( item2, entry );
if( Objects.equals(item1, item2) ){
loopedLinkCount++;
}
}
/**
*
* @param key
* @return an entry containing the key and it's one to one mapping or null if there is
* no mapping for the key.
*/
public Entry<T1, T2> get( Object key )
{
return mappings.get( key );
}
public Entry<T1, T2> remove( Object key )
{
Entry<T1, T2> entry = mappings.remove( key );
if( entry == null ){
return null;
}
if( Objects.equals( entry.item2, entry.item1 ) ){
loopedLinkCount--;
return entry;
}
return mappings.remove( Objects.equals( key, entry.item1 ) ? entry.item2 : entry.item1 );
}
public Set< Entry<T1, T2> > entrySet()
{
return new HashSet<>( mappings.values() );
}
public int size()
{
return ( mappings.size() + loopedLinkCount ) / 2;
}
}