7

Is it possible (In Java) to create a Map where, no matter what key I was to search for, I would retrieve the same value? We can assume either a finite or infinite amount of keys.

I considered a map of size 1 and load factor of 1.0, with that value stored in it, but I'm nearly positive that the hashmap implementation will recognize the collision, and return null anyway.

I also entertained the possibility that if I created my own hashfunction for a variable, or even a new datatype that implemented Map, that I should be able to do this, but it may be a little messy. Perhaps not?

Of course, simply mapping the value to every single key would be very inefficient (unless there is a built in method for this, that I overlooked), and nowhere near as entertaining as hearing SO's answers.

Addison
  • 7,322
  • 2
  • 39
  • 55

3 Answers3

6

I suppose the most reasonable way to do this with existing API is like the following:

// Java 6/7
new TreeMap<K, V>(new Comparator<K>() {
    @Override
    public int compare(K lhs, K rhs) {
        return 0;
    }
});

// Java 8+
new TreeMap<K, V>((a, b) -> 0);

This TreeMap considers all keys equal but will otherwise maintain pretty good Map semantics.

Note that the first key you put in the Map will stay in it forever unless you remove it.

i.e.

m.put("abc", "123");
m.put("def", "456");
// prints something like {abc=456}
System.out.println(m);

So you might keep that in mind for example if you planned on examining the entrySet.

Radiodef
  • 37,180
  • 14
  • 90
  • 125
1

I'm not too sure on what you're trying to accomplish here but all you need to do is implement Map. An example:

import java.util.Collection;
import java.util.Map;
import java.util.Set;

public class ImmutableMap<K, V> implements Map<K, V> {

    private final V immutableValue;

    public ImmutableMap(final V immutableValue) {
        this.immutableValue = immutableValue;
    }

    @Override
    public int size() {
        return 0;
    }

    @Override
    public boolean isEmpty() {
        return false;
    }

    @Override
    public boolean containsKey(Object key) {
        return false;
    }

    @Override
    public boolean containsValue(Object value) {
        if (value == immutableValue)
            return true;
        return false;
    }

    @Override
    public V get(Object key) {
        return immutableValue;
    }

    @Override
    public V put(K key, V value) {
        throw new UnsupportedOperationException();
    }

    @Override
    public V remove(Object key) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void clear() {
        throw new UnsupportedOperationException();
    }

    /**
     * Below are some unnecessary methods for the purpose of this class.
     * You may decide their action.
     */

    @Override
    public Set<K> keySet() {
        return null;
    }

    @Override
    public Collection<V> values() {
        return null;
    }

    @Override
    public Set<java.util.Map.Entry<K, V>> entrySet() {
        return null;
    }

}
Pavan P
  • 645
  • 8
  • 17
  • Yes, this was what I was considering. It just seemed like a less than ideal situation, since it creates a class that will only be used once. – Addison Feb 17 '15 at 05:06
  • 4
    You should implement Map instead of HashMap and implement all methods correctly. – Adrian Leonhard Feb 17 '15 at 05:07
  • I am not able to understand that `immutableValue` is not mapped to any key, and `put` function is not available. So it is similar to normal `dto` which can hold the same data without extending to HashMap. Please correct me if I am going wrong anywhere in my understanding. – Naman Gala Feb 17 '15 at 05:07
1

I'm not sure what you are trying to accomplish, I guess Map with default value should work for you. This is pretty standard pattern.

  1. You can either use apache commons DefaultedMap implementation

  2. In Java 8, you can use Map.getOrDefault

  3. You can always implement your own

HashMap to return default value for non-found keys?

Community
  • 1
  • 1
mavarazy
  • 7,562
  • 1
  • 34
  • 60