Несовместимые общие подстановочные знаки

В следующем фрагменте:

package test;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

public class WildcardsTest<K, V> {
    private Iterator<Map.Entry<K, ? extends Collection<V>>> iterator;
    public WildcardsTest(Map<K, ? extends Collection<V>> map) {
        iterator = map.entrySet().iterator();
        /* Type mismatch: cannot convert from
           Iterator<Map.Entry<K,capture#1-of ? extends Collection<V>>> to
           Iterator<Map.Entry<K,? extends Collection<V>>> */
    }
}

Назначение неверно, хотя типы, кажется, точно совпадают.

Я разработал грязный обходной путь, указав тип Collection в качестве другого универсального параметра, например так:

public class WildcardsTest<K, V, C extends Collection<V>> {
    private Iterator<Map.Entry<K, C>> iterator;
    public WildcardsTest(Map<K, C> map) {
        iterator = map.entrySet().iterator();
    }
}

Но это C Параметр действительно является типом "все равно", который только усложняет API, есть ли способ избавиться от него при сохранении безопасности типов?

Благодарю.

2 ответа

Решение

Сделайте так, и это будет работать:

private final Iterator<? extends
    Map.Entry<K, ? extends Collection<V>>
> iterator;

Вы все еще можете использовать итератор следующим образом:

public void foo(){
    while(iterator.hasNext()){
        Entry<K, ? extends Collection<V>> entry = iterator.next();
        Collection<V> value = entry.getValue();
    }
}

Для справки прочтите принцип получения и сдачи (изначально из Java Generics and Collections)

Назначение неверно, хотя типы, кажется, точно совпадают.

Два ?карточки могут быть связаны с двумя разными классами. Проще говоря, совершенно очевидно, что существует несоответствие типов:

private Iterator<Map.Entry<K, ArrayList<V>>> iterator;
public WildcardsTest(Map<K, HashSet<V>> map) {
    iterator = map.entrySet().iterator();
}

Когда вы вводите Cвы "заставляете их" относиться к одному и тому же классу.

Другие вопросы по тегам