Целью этого практического задания - изучить применение обобщений в Java путем разработки класса Pair
, который
представляет собой кортеж из двух элементов.
Кортеж - это иммутабельная упорядоченная последовательность элементов. Кортеж из двух элементов содержит два элемента, а набор из трех элементов содержит три элемента, набор из n - содержит n элементов.
Класс Pair
может быть полезен в дальнейшем при необходимости хранить данные, которые встречаются в виде упорядоченной пары:
имя и фамилия, двумерные координаты и т.д.
Проблема при разработке этого класса заключается в том, что мы не хотим заранее указывать типы данных элементов.
Цель состоит в том, чтобы разработать один класс Pair
, который можно было бы использовать для хранения пар объектов любого типа.
Один из возможных вариантов решения поставленной задачи состоит в разработке класса Pair
так, чтобы типы двух
элементов были объявлены как Object
.
Поскольку каждый ссылочный тип в Java наследуется от Object
, этот подход даст нам желаемую гибкость.
Откройте следующие два класса, которые находятся в пакете org.itstep.step01, в любой среде разработки (например, в Intellij Idea):
- ObjectPair.java [ЗАВЕРШЕН]
- ObjectPairDriver.java [НЕЗАКОНЧЕН]
Уделите время, чтобы прочитать код и комментарии к нему, а затем выполните следующие действия:
-
Предоставленный код компилируется, но в основном методе есть логическая ошибка, которая, вероятно, приведет к ошибке времени выполнения, когда вы в методе
largestStadium()
будете обходить в цикле массива стадионов. Найдите проблему и устраните ее. -
Реализуйте метод
largestStadium()
, который должен вернуть название наибольшего стадиона. Внимательно читайте комментарии Javadoc. Проверьте, работает ли метод должным образом. (ПОДСКАЗКА: вам нужно будет выполнить несколько приведений при извлечении элементов из кортежа.) -
БОНУСНЫЙ ВОПРОС: Почему компилируется эта строка кода?
stadiums[0] = new ObjectPair("Bridgeforth Stadium", 25000);
Обратите внимание, что формальные и фактические типы параметров не совпадают. Ожидаемый тип второго параметра - Object
(ссылочный тип), а предоставленный аргумент - 1
(примитивное значение).
Если вы не знаете ответа на этот вопрос, погуглите термин Autoboxing (Автоупаковка).
-
Создайте копию класса
ObjectPair
с именемPair
в пакете org.itstep.step02. Сделайте этот класс обобщенным. Ваш обновленный класс должен позволять независимо указывать типы первого и второго элементов. -
Создайте копию класса
ObjectPairDriver
с именемPairDriver
в пакете org.itstep.step02. Реорганизуйте этот класс таким образом, чтобы он использовал ваш классPair
. Функционал должен остаться без изменений. Результирующий код не должен содержать никаких операций приведения. -
БОНУСНЫЙ ВОПРОС: Что произойдет, если вы повторно воспроизведете проблему, которую вы исправили на шаге 1 из предыдущего блока? Будет ли компилироваться полученный код? Как вы думаете, почему обобщенные классы коллекций иногда называют «типобезопасными» коллекциями?
-
БОНУСНЫЙ ВОПРОС: Перечислите некоторые причины, по которым класс
Pair
может быть предпочтительнее классаObjectPair
. Можете ли вы предположить ситуации, в которых классObjectPair
может быть предпочтительнее классаPair
?
Теперь, когда у вас есть завершенный универсальный класс Pair
, создайте минимально функционирующую коллекцию объектов Pair
.
Откройте следующие файлы из пакета org.itstep.step03:
- Pairs.java [НЕЗАКОНЧЕН]
- PairsDriver.java [ЗАВЕРШЕН]
Уделите некоторое время, для того, чтобы прочитать код и комментарии Javadoc, а затем выполните следующие действия:
-
Уберите однострочные комментарии в классе Pairs.java.
-
Объявите массив объектов
Pair
фиксированного размера, который использует универсальные типы. При необходимости объявляйте дополнительных членов, чтобы отслеживать количество добавленных пар. -
Завершите конструктор. К сожалению, в Java невозможно напрямую создать массив обобщенных объектов.
Этот код не скомпилируется:
pairs = new Pair<K, V>[CAPACITY];
В этом случае самое простое решение - использовать так называемый "сырой" ("raw") массив:
pairs = new Pair[CAPACITY];
Это приведет к появлению предупреждения в строке "Type safety: The expression of type Pair[] needs unchecked conversion to conform to Pair[]" («Безопасность типов: выражение типа Pair[] требует неконтролируемого преобразования. чтобы соответствовать Pair[] ", которое может быть подавлено с помощью аннотации @SuppressWarnings ("unchecked").
ПРИМЕЧАНИЕ. В 99% случаев подавление предупреждений является ПЛОХОЙ ИДЕЕЙ. Это редкое исключение.
-
Завершите метод
addPair()
, который должен вернутьfalse
, если массив уже заполнен. -
Реализуйте требуемые методы итератора. При удалении объекта
Pair
все оставшиеся элементы должны сдвинуться на одно место влево. -
Выбросите исключение, как указано в [API Java Iterator] (https://docs.oracle.com/javase/10/docs/api/java/util/Iterator.html).
-
Снимите однострочные комментарии с класса PairsDriver.java и запустите код на выполнение
Откройте файл CompileDriver.java и пока НЕ УБИРАЙТЕ КОММЕНТАРИИ со строк кода.
Прокомментируйте каждый оператор присваивания одним из следующих способов:
// Да (Для случая если скомпилируется)
или
// Нет (Для случая, если не скомпилируется)
Для тех строк, которые не будут компилироваться, добавьте пояснение проблемы. Как только все будет готово, проверьте свои ответы, раскомментировав строки и запустить на компиляцию файл.
Закомментируйте некомпилируемые строки перед отправкой.
Для проверки правильности решения запустите тесты. Для задания 2 и 3 необходимо раскомментировать методы в тестах PairTest, PairDirverTest и PairsTest.