javagenericsjava-8type-erasurename-clash

Java name clash error, despite different method signatures


For fun, I'm trying to implement a "MultiMap" collection, like what already exists in the Apache Commons library. I'm getting an interesting error with my "remove(K key, V value)" method. The compiler says that there is a name clash - that it has the same erasure as "remove(Object, Object) of type Map". But there is no such method defined in the java.util.Map interface! Only a "remove(Object)" method - with one parameter, as opposed to my two parameter version. What's even more interesting is that if you manually remove the type information by replacing my "remove(K key, V value)" with "remove(Object key, Object value)", it compiles fine. Can anyone explain this phenomenon?

I'm running Java 8, in case that matters.

import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MultiMap<K, V> extends AbstractMap<K, Collection<V>>
{
    private Map<K, Collection<V>> map;

    public MultiMap()
    {
        super();
        map = new HashMap<>();
    }

    //Fine
    public void clear(K key)
    {
        get(key).clear();
    }

    //Fine
    public boolean add(K key, V value)
    {
        if(!containsKey(key))
            put(key, new ArrayList<>());
        return get(key).add(value);
    }

    //KABOOM!!
    //"Name clash: The method remove(K, V) of type MultiMap<K,V> has the same erasure as remove(Object, Object) of type Map<K,V> but does not override it"
    public boolean remove(K key, V value)
    {
        if(!containsKey(key))
            return false;
        return get(key).remove(value);
    }

    @Override public Collection<V> put(K key, Collection<V> values)
    {
        return map.put(key, values);
    }

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

Solution

  • But there is no such method defined in the java.util.Map interface!

    There is a Map#remove(Object, Object) method in the Map interface; it was added in Java 8. Hence the error.