public static
assert checkMap!=null;
boolean result = false;
Collection
Думал, что более менее разобрался с дженериками, однако, в упор не понимаю, почему в строке: checkMap.put(key, new ArrayList
Wrong 2nd argument type. Found: 'java.util.ArrayList', required: '? extends java.util.Collection
Сначала в сигнатуре метода было : K key, V value, Map
UDP: Также, возникает вопрос. Почему, если заменить в сигнатуре ? extends Collection на ? super Collection, пропадает доступ к методам коллекции? Ведь вроде ? super Collection ограничивает самой коллекцией и ее родителями?
Ответ
Забудем пока про конкретно ваш код и рассмотрим более простой пример. Допустим, есть вот такие классы:
// Для демонстрации иерархии типов
class A { }
class B extends A { }
class C extends B { }
// Для демонстрации контейнера
class S
public V get() { return value; }
public void set(V value) { this.value = value; }
}
Рассмотрим такой контейнер, как S. Каким будет возвращаемое значение для метода get? Этот метод вернет что-то, что является наследником B. То есть, что бы метод get ни вернул - это что-то можно записать в переменную типа B.
S s;
B v = s.get(); // Значение типа ? extends B всегда можно записать в переменную типа B
Теперь рассмотрим метод set. Кажется, что все нормально? Но давайте сделаем вот так:
S s = new S
Здесь я создал конкретный контейнер для примера. Даже если на самом деле используется S - компилятор должен обеспечить корректность кода в любом случае.
Теперь рассмотрим такой контейнер как S. Метод set у него можно вызвать с параметром типа B
S s;
s.set(new B()); // Значение типа B всегда можно передать как ? super B
А вот метод get нормально вызвать не получится:
S s = new S();
B v = s.get(); // Ошибка - попытались значение типа A записать в переменную типа B
В итоге получается, что get-методы требуют отношения extends, а set-методы требуют отношения super. Если вашему коду нужно использовать оба типа методов - придется определять оба отношения одновременно, т.е. оставить просто
Возвращаюсь к вашему коду, можно заметить, что из параметра checkMap вы одновременно получаете данные (get) - и передаете их ему (put). Поэтому, вы не можете использовать ? extends ... в определении параметра. Единственный способ сделать оба вызова рабочими - использовать конкретный тип данных. Например, Map
Если же вам нужно работать с разными отображениями - то сам тип коллекции надо делать обобщенным: Map
public static
public static
Смысл фабрики - в том, что ее создает тот код, который знает точный тип коллекции:
Map> factory1 = () -> new ArrayList
Map
Дальше фабрика по цепочке вызовов передается пока не придет в метод addToGroupMap
Комментариев нет:
Отправить комментарий