maxchv / Lesson028

Generics

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Практика на работу с Обобщениями (Generics)

Целью этого практического задания - изучить применение обобщений в Java путем разработки класса Pair, который представляет собой кортеж из двух элементов.

Кортеж - это иммутабельная упорядоченная последовательность элементов. Кортеж из двух элементов содержит два элемента, а набор из трех элементов содержит три элемента, набор из n - содержит n элементов.

Класс Pair может быть полезен в дальнейшем при необходимости хранить данные, которые встречаются в виде упорядоченной пары: имя и фамилия, двумерные координаты и т.д.

Проблема при разработке этого класса заключается в том, что мы не хотим заранее указывать типы данных элементов.

Цель состоит в том, чтобы разработать один класс Pair, который можно было бы использовать для хранения пар объектов любого типа.

Задания

Задание 1. Использование Object

Один из возможных вариантов решения поставленной задачи состоит в разработке класса Pair так, чтобы типы двух элементов были объявлены как Object.

Поскольку каждый ссылочный тип в Java наследуется от Object, этот подход даст нам желаемую гибкость.

Откройте следующие два класса, которые находятся в пакете org.itstep.step01, в любой среде разработки (например, в Intellij Idea):

Уделите время, чтобы прочитать код и комментарии к нему, а затем выполните следующие действия:

  1. Предоставленный код компилируется, но в основном методе есть логическая ошибка, которая, вероятно, приведет к ошибке времени выполнения, когда вы в методе largestStadium() будете обходить в цикле массива стадионов. Найдите проблему и устраните ее.

  2. Реализуйте метод largestStadium(), который должен вернуть название наибольшего стадиона. Внимательно читайте комментарии Javadoc. Проверьте, работает ли метод должным образом. (ПОДСКАЗКА: вам нужно будет выполнить несколько приведений при извлечении элементов из кортежа.)

  3. БОНУСНЫЙ ВОПРОС: Почему компилируется эта строка кода?

   stadiums[0] = new ObjectPair("Bridgeforth Stadium", 25000);

Обратите внимание, что формальные и фактические типы параметров не совпадают. Ожидаемый тип второго параметра - Object (ссылочный тип), а предоставленный аргумент - 1 (примитивное значение). Если вы не знаете ответа на этот вопрос, погуглите термин Autoboxing (Автоупаковка).

Задание 2. Обобщения

  1. Создайте копию класса ObjectPair с именем Pair в пакете org.itstep.step02. Сделайте этот класс обобщенным. Ваш обновленный класс должен позволять независимо указывать типы первого и второго элементов.

  2. Создайте копию класса ObjectPairDriver с именем PairDriver в пакете org.itstep.step02. Реорганизуйте этот класс таким образом, чтобы он использовал ваш класс Pair. Функционал должен остаться без изменений. Результирующий код не должен содержать никаких операций приведения.

  3. БОНУСНЫЙ ВОПРОС: Что произойдет, если вы повторно воспроизведете проблему, которую вы исправили на шаге 1 из предыдущего блока? Будет ли компилироваться полученный код? Как вы думаете, почему обобщенные классы коллекций иногда называют «типобезопасными» коллекциями?

  4. БОНУСНЫЙ ВОПРОС: Перечислите некоторые причины, по которым класс Pair может быть предпочтительнее класса ObjectPair. Можете ли вы предположить ситуации, в которых класс ObjectPair может быть предпочтительнее класса Pair?

Задание 3. Итераторы

Теперь, когда у вас есть завершенный универсальный класс Pair, создайте минимально функционирующую коллекцию объектов Pair.

Откройте следующие файлы из пакета org.itstep.step03:

Уделите некоторое время, для того, чтобы прочитать код и комментарии Javadoc, а затем выполните следующие действия:

  1. Уберите однострочные комментарии в классе Pairs.java.

  2. Объявите массив объектов Pair фиксированного размера, который использует универсальные типы. При необходимости объявляйте дополнительных членов, чтобы отслеживать количество добавленных пар.

  3. Завершите конструктор. К сожалению, в 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% случаев подавление предупреждений является ПЛОХОЙ ИДЕЕЙ. Это редкое исключение.

  4. Завершите метод addPair(), который должен вернуть false, если массив уже заполнен.

  5. Реализуйте требуемые методы итератора. При удалении объекта Pair все оставшиеся элементы должны сдвинуться на одно место влево.

  6. Выбросите исключение, как указано в [API Java Iterator] (https://docs.oracle.com/javase/10/docs/api/java/util/Iterator.html).

  7. Снимите однострочные комментарии с класса PairsDriver.java и запустите код на выполнение

Задание 4. Wildcards и подклассы

Откройте файл CompileDriver.java и пока НЕ УБИРАЙТЕ КОММЕНТАРИИ со строк кода.

Прокомментируйте каждый оператор присваивания одним из следующих способов:

// Да (Для случая если скомпилируется)

или

// Нет (Для случая, если не скомпилируется)

Для тех строк, которые не будут компилироваться, добавьте пояснение проблемы. Как только все будет готово, проверьте свои ответы, раскомментировав строки и запустить на компиляцию файл.

Закомментируйте некомпилируемые строки перед отправкой.

Проверка решения

Для проверки правильности решения запустите тесты. Для задания 2 и 3 необходимо раскомментировать методы в тестах PairTest, PairDirverTest и PairsTest.

Ссылки

About

Generics


Languages

Language:Java 100.0%