2014-05-21 13 views
8

Per divertimento, sto cercando di implementare una raccolta "MultiMap", come quello che già esiste nella libreria Apache Commons. Sto ottenendo un errore interessante con il mio metodo "remove (tasto K, valore V)". Il compilatore dice che c'è un conflitto di nomi - che ha la stessa cancellazione di "remove (Object, Object) di tipo Map". Ma non esiste un tale metodo definito nell'interfaccia java.util.Map! Solo un metodo "remove (Object)" - con un parametro, a differenza della mia versione a due parametri. Ciò che è ancora più interessante è che se si rimuovono manualmente le informazioni sul tipo sostituendo il mio "remove (chiave K, valore V)" con "remove (Chiave dell'oggetto, valore dell'oggetto)", vengono compilate correttamente. Qualcuno può spiegare questo fenomeno?Errore di conflitto nome Java, nonostante le diverse firme del metodo

Sto eseguendo Java 8, nel caso che importi.

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(); 
    } 
} 
+0

Hm Non ricevo un errore lì. Io * sto * ricevendo un errore con la chiamata 'put (key, new ArrayList <>())', comunque. (Modifica: ho provato questo con Java 7.) – arshajii

+0

Interessante. Forse la versione è importante? Sto usando Java 8. – TheBrownMotie

+0

@ TheBrownMotie Penso che sia importante. Ho già visto un paio di comportamenti strani compili su SO. –

risposta

13

Ma non c'è tale metodo definito nell'interfaccia java.util.Map!

Ci è un metodo Map#remove(Object, Object) nell'interfaccia Map; è stato aggiunto in Java 8. Quindi l'errore.

+0

Oh wow ... Stavo guardando l'API Java 7. Grazie, accetterò la tua risposta quando me lo permetterà. – TheBrownMotie

1

Questo è dovuto a processo di cancellazione tipo quando un tipo generico java viene tradotto in bytecode.

In fase di esecuzione il default boolean remove(Object key, Object value) (questo metodo è nuovo in Java 8) in Map è lo stesso del metodo in classe MultiMap public boolean remove(K key, V value).

Il compilatore vede questo, e quindi mostra l'errore:

Nome scontro: Il metodo remove (K, V) di tipo MultiMap ha lo stesso cancellazione quanto remove (Object, Object) di tipo AbstractMap ma fa non sostituirlo.

vedere questo: http://docs.oracle.com/javase/tutorial/java/generics/genTypes.html

Problemi correlati