Несколько границ в Java
Иногда одного ограничения T extends SomeType
недостаточно: тип должен одновременно поддерживать
два интерфейса. В Java дополнительные границы
перечисляют через & сразу после первой
границы в объявлении параметра типа.
Копирование в изменяемый список требует и сравнимости элементов, и возможности клонировать значение через интерфейс:
interface Copyable<T> {
T copy();
}
class Duplicator {
static <T extends Comparable<T> & Copyable<T>> void duplicateAll(
List<T> source,
List<T> target
) {
source.stream().sorted().map(Copyable::copy).forEach(target::add);
}
}
Класс может реализовать обе границы, тогда
внутри метода можно и сортировать, и вызывать
copy:
record Score(int points) implements Comparable<Score>, Copyable<Score> {
@Override
public int compareTo(Score other) {
return Integer.compare(points, other.points);
}
@Override
public Score copy() {
return new Score(points);
}
}
void demo() {
List<Score> src = List.of(new Score(30), new Score(10), new Score(20));
List<Score> dst = new ArrayList<>();
Duplicator.duplicateAll(src, dst);
System.out.println(dst.stream().map(Score::points).toList());
}
Первая граница может быть классом, остальные -
только интерфейсы. Порядок важен: класс пишут
один раз в начале цепочки extends.
Объявите интерфейс с методом без аргументов, который возвращает строковую метку. Сделайте метод, который принимает список элементов, сортирует его и выводит метки через запятую. Ограничьте тип так, чтобы элементы можно было сортировать и получать из них метку.
Для трех чисел 5, 1, 3
оберните их в тип, который реализует обе
границы из примера урока, скопируйте в
новый список через метод урока и выведите
очки по порядку.