2014-05-21 29 views
8

Dla zabawy próbuję zaimplementować kolekcję "MultiMap", taką jak to, co już istnieje w bibliotece Apache Commons. Otrzymuję interesujący błąd z metodą "remove (K key, V value)". Kompilator mówi, że istnieje konflikt nazwy - że ma to samo usunięcie jak "remove (Object, Object) typu Map". Ale nie ma takiej metody zdefiniowanej w interfejsie java.util.Map! Tylko metoda "remove (Object)" - z jednym parametrem, w przeciwieństwie do mojej wersji z dwoma parametrami. Jeszcze bardziej interesujące jest to, że jeśli ręcznie usuniesz informacje o typie, zastępując moje "usuń (klucz K, wartość V)" za pomocą "remove (Object key, Object value)", kompiluje się dobrze. Czy ktoś może wyjaśnić to zjawisko?Błąd nazwy nazwy Java, pomimo różnych podpisów metod.

Używam Java 8, na wszelki wypadek.

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 ja nie dostaję błąd istnieje. I * am * otrzymuję błąd z wywołaniem 'put (key, new ArrayList <>())'. (Edycja: próbowałem tego z Java 7.) – arshajii

+0

Interesujące. Być może wersja ma znaczenie? Używam Java 8. – TheBrownMotie

+0

@TheBrownMotie Myślę, że to ma znaczenie. Widziałem już kilka kompilacji dziwnych zachowań na SO. –

Odpowiedz

13

Ale nie ma takiej metody zdefiniowane w interfejsie java.util.Map!

nie jestMap#remove(Object, Object) Sposób interfejsu Map; został dodany w Javie 8. Stąd błąd.

+0

Oh wow ... Patrzyłem na API Java 7. Dzięki, przyjmuję twoją odpowiedź, kiedy mi pozwoli. – TheBrownMotie

1

Jest to spowodowane usunięciem typu typu, gdy typ ogólny Java jest tłumaczony na kod bajtowy.

W środowisku wykonawczym default boolean remove(Object key, Object value) (ta metoda jest nowa w języku Java 8) w programie Map jest taka sama jak w przypadku metody MultiMap klasy public boolean remove(K key, V value).

Kompilator widzi to, a więc pokazuje błąd:

Nazwa zderzenie: metoda usuwania, (K, V) typu MultiMap ten sam usunięcia jako usuwania (obiektu, obiekt) typu AbstractMap lecz nie a nie przesłonić go.

Zobacz to: http://docs.oracle.com/javase/tutorial/java/generics/genTypes.html