Производитель и потребитель в Java
На практике легко перепутать, когда ставить
extends, а когда super в
подстановочном типе. Короткая памятка на
английском звучит как PECS: producer extends,
consumer super. Производитель отдает элементы -
нужна верхняя граница, потребитель принимает -
нижняя.
Метод, который только читает числа из списка,
объявляют с ? extends Number. Список
выступает производителем значений:
class Stats {
static double average(List<? extends Number> source) {
if (source.isEmpty()) {
return 0;
}
double sum = 0;
for (Number value : source) {
sum += value.doubleValue();
}
return sum / source.size();
}
}
void demo() {
System.out.println(Stats.average(List.of(1, 2, 4)));
}
Метод, который копирует числа в другой список,
принимает приемник с ? super Integer.
Целевой список - потребитель:
class Copy {
static void copyInts(List<? extends Integer> from, List<? super Integer> to) {
to.clear();
to.addAll(from);
}
}
void demo() {
List<Integer> src = List.of(3, 5);
List<Number> dst = new ArrayList<>();
Copy.copyInts(src, dst);
System.out.println(dst);
}
Если параметр и читает, и пишет в один и тот
список, подстановочный тип обычно не подходит -
остается точный параметр типа T. Правило
PECS помогает выбирать границу для односторонних
операций.
Напишите метод, который находит максимальное
число в списке-производителе с верхней
границей по Number. Проверьте на
2, 9, 4 и выведите ответ.
Сделайте метод, который переносит все строки
из одного списка в другой: источник с
верхней границей по String, приемник
с нижней. Проверьте на двух коротких словах
и выведите приемник.