Question

I am wondering if there is a data structure that can store one to one relationship in Java.

For example, for mapping the month of the year with its number and vice versa.

I know I can use two HashMaps, but I want to know if there is another data structure that also checks the value when I put a new pair.

Was it helpful?

Solution

There is none in standard Java though. You can however use Guava's BiMap if you can use a 3rd party library.

A bimap (or "bidirectional map") is a map that preserves the uniqueness of its values as well as that of its keys. This constraint enables bimaps to support an "inverse view", which is another bimap containing the same entries as this bimap but with reversed keys and values.

OTHER TIPS

There is no data structure for that, but I think you can use a parameterized Pair for this task. This class is so popular that you will it on the internet.

Here is one on SO: Generic pair class

Needed a solution to this recently, but didn't want to rely on a plugin....so I extended the base Java Class. This implementation does not allow null values.

public class OneToOneMap<K,V> extends HashMap<K,V> {
    public OneToOneMap() {
        super();
    }
    public OneToOneMap(int initialCapacity) {
        super(initialCapacity);
    }
    public OneToOneMap(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor);
    }
    public OneToOneMap(Map<? extends K, ? extends V> m) {
        super(m);
        dedup();
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m){
        super.putAll(m);
        dedup();
    }

    @Override
    public V put(K key, V value) {
        if( key == null || value == null ) return null;
        removeValue(value);
        return super.put(key,value);
    }

    public K getKey( V value ){
        if( value == null || this.size() == 0 ) return null;
        Set<K> keys = new HashSet<>();
        keys.addAll(keySet());
        for( K key : keys ){
            if( value.equals(get(key) )) return key;
        }
        return null;
    }
    public boolean hasValue( V value ){
        return getKey(value) != null;
    }
    public boolean hasKey( K key ){
        return get(key) != null;
    }

    public void removeValue( V remove ){
        V value;
        Set<K> keys = new HashSet<>();
        keys.addAll(keySet());
        for( K key : keys ){
            value = get(key);
            if( value == null || key == null || value.equals(remove)) remove(key);
        }        
    }
    //can be used when a new map is assigned to clean it up
    public void dedup(){
        V value;
        Set<V> values = new HashSet<>();
        Set<K> keys = new HashSet<>();
        keys.addAll(keySet());
        for( K key : keys ){
            value = get(key);
            if( value == null || key == null || values.contains(value) ) remove(key);
            else values.add(value);
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top