Java: Дженерики
Теория: Реализация дженериков
Попрактикуемся в создании дженериков на примере такой коллекции как пара. Подобный тип данных встречается во многих языках и имитируется в Java с помощью мапы: Map.entry(key, value). Пара содержит два элемента, которые можно получить из пары и установить новые. Простейший пример использования пары – это точки на плоскости.
Один параметр типа
Начнем с примера. Ниже код использования пары как точки на плоскости.
Для простоты наша пара будет работать с одним параметром типа, который определяет тип обоих значений в паре. Напишем соответствующий класс:
Для того чтобы дженерики понимались проще, можно представлять дженерик как определение метода. В угловых скобках указывается имя параметра, который будет передан внутрь при "вызове дженерика". Внутри этот параметр используется уже без скобок. Даже в определении методов, которые ожидают данные этого типа как параметры.
Синтаксически в определении методов ничего не поменялось, кроме того, что вместо конкретного типа мы подставляем параметр типа T. В случае геттеров мы возвращаем данные этого типа, в случае сеттеров - получаем на вход.
Теперь создадим дженерик-интерфейс, по аналогии с интерфейсом List.
И реализуем его.
Параметр типа указывается и для класса и для интерфейса. В остальном в классе ничего не меняется. Сделав такое изменение, мы получаем возможность подменять реализацию. В случае с парами это не очень актуально, но общая концепция становится понятна.
Два параметра типа
Изменим нашу пару так, чтобы тип каждого параметра выбирался независимо. Пример использования.
Сначала поправим интерфейс.
Два параметра типа выглядят как параметры в определении метода. В этот раз, для удобства восприятия, взяты имена L и R. Порядок параметров типов мы определяем сами, в данном случае логично разместить слева параметр отвечающий за left, а справа отвечающий за right.
Следующий шаг поменять класс.
И последнее, что мы сделаем, добавим конструктор, который позволяет передавать значения для пары в одну строку. Кроме того, в таком случае, компилятор автоматически выводит тип передаваемых значений, что позволяет не прописывать явно параметры типов.
Реализация:



