Расширить возможности классов, связанных с табулированными функциями, переопределив в них методы, унаследованные из класса Object
.
Переопределите в классе FunctionPoint
следующие методы.
• String toString()
: Должен возвращать текстовое описание точки. Например: (1.1; -7.5)
, где 1.1
и -7.5
– абсцисса и ордината точки соответственно.
• boolean equals(Object o)
: Должен возвращать true
тогда и только тогда, когда переданный объект также является точкой и его координаты в точности совпадают с координатами объекта, у которого вызывается метод.
• int hashCode()
: Должен возвращать значение хэш-кода для объекта точки. Можно выбрать реализацию хэш-функции или воспользоваться простейшей реализацией, основанной на применении операции исключающего ИЛИ (XOR
). В этом случае хэш-код рассчитывается как побитовое XOR
для набора значений типа int
. Этот набор должен включать в себя всю информацию, описывающую состояние объекта, т.е. два значения координат. Поскольку они имеют тип double
, необходимо без потерь перевести эту информацию к типу int
, например, представив одно значение типа double
(8 байт) как два значения типа int
(4 байта и 4 байта). Сделать это можно с помощью метода Double.doubleToLongBits()
, оператора побитового И (&
) (для выделения младших четырёх байтов) и оператора битового логического сдвига (>>
) (для выделения старших четырёх байтов).
• Object clone()
: Должен возвращать объект-копию для объекта точки. Достаточно простого клонирования, так как точка не имеет ссылок на другие объекты.
Переопределите в классе ArrayTabulatedFunction
следующие методы.
• String toString()
: Должен возвращать описание табулированной функции. Например: {(0.0; 1.2), (1.0; 3.8), (2.0; 15.2)}
, где в круглых скобках указываются координаты точек.
• boolean equals(Object o)
: Должен возвращать true
тогда и только тогда, когда переданный объект также является табулированной функцией (реализует интерфейс TabulatedFunction
) и её набор точек в точности совпадает с набором точек функции, у которой вызывается метод. В случае если переданный объект является экземпляром класса ArrayTabulatedFunction
, время работы метода должно быть сокращено за счёт прямого обращения к элементам состояния переданного объекта.
• int hashCode()
: Должен возвращать значение хэш-кода для объекта табулированной функции. Можно выбрать реализацию хэш-функции или воспользоваться простейшей реализацией, основанной на применении операции исключающего ИЛИ (XOR
). В этом случае хэш-код рассчитывается как побитовое XOR
для набора значений типа int
. В данный набор входят хэш-коды всех точек табулированной функции, а также количество точек в функции. Последнее нужно для того, чтобы значения хэш-кода были различны для функций, отличающихся наличием нулевой точки (например, {(-1; 1), (0; 0), (1, 1)}
и {(-1; 1), (1, 1)}
).
• Object clone()
: Должен возвращать объект-копию для объекта табулированной функции. Поскольку табулированная функция ссылается на другие объекты, клонирование должно быть глубоким.
Аналогично, переопределите методы toString()
, equals()
, hashCode()
и clone()
в классе LinkedListTabulatedFunction
. При написании методов учтите следующие особенности.
• Метод equals()
также должен корректно работать при сравнении с любым объектом типа TabulatedFunction
, а при сравнении с объектом типа LinkedListTabulatedFunction
время работы метода должно быть сокращено за счёт возможности прямого обращения к полям переданного объекта.
• Клонирование в методе clone()
тоже должно быть глубоким, однако классическое глубокое клонирование в данном случае не совсем разумно. Если сделать объекты класса FunctionNode
клонируемыми, после их клонирования значения полей ссылок придётся изменить (т.к. они будут ссылаться на объекты из исходного списка), и значение ссылающегося на объект точки поля тоже придётся изменить (т.к. его нужно будет заменить клоном объекта точки). Поэтому проще окажется «пересобрать» новый объект списка, причём сделать это проще без использования методов добавления в список, т.к. это приведёт к выполнению большого количества нерезультативных операций и заметно скажется на скорости выполнения программы.
Сделайте так, чтобы все объекты типа TabulatedFunction
были клонируемыми с точки зрения JVM и внесите метод clone()
в этот интерфейс.
Проверьте работу написанных методов.
• Проверьте работу метода toString()
для объектов типов ArrayTabulatedFunction
и LinkedListTabulatedFunction
, выведя строковое представление объектов в консоль.
• Проверьте работу метода equals()
, вызывая его для одинаковых и различающихся объектов одинаковых и различающихся классов.
• Проверьте работу метода hashCode()
, выведя в консоль его значения для всех использованных объектов. Убедитесь в согласованности работы методов equals()
и hashCode()
. Также попробуйте незначительно изменить один из объектов (например, изменить одну из координат одной из точек на несколько тысячных) и проверьте, как изменится значение хэш-кода объекта.
• Проверьте работу метода clone()
для объектов обоих классов табулированных функций. Убедитесь, что произведено именно глубокое клонирование: для этого после клонирования измените исходные объекты и проверьте, что объекты-клоны не изменились.
Что должно быть в репозитории, помимо файлов задания:
- Класс
Main
как описано в задании 5. - Отчет в формате
.pdf
, в котором описано выполнение работы.
Короткий, но содержательный (до 10`000 символов).
- Для каждого задания опишите ход выполнения и результат.
- На титульном листе укажите название и номер лабораторной работы, а также свои ФИО и группу.
- (Опционально) Добавьте содержание документа с работающими ссылками.
- Текст читаемый - от 12 pt.
- Скриншоты или, что предпочтительнее, текст работы с консолью.
- Файл отчёта формата
.pdf
. Имя файла: report.pdf
Для сдачи лабораторной работы:
- Сделайте fork репозитория с заданием.
- Залейте код и отчёт. Убедитесь, что репозиторий содержит всё необходимое для сдачи и не содержит ненужные файлы (занесите их в
.gitignore
). - Откройте PR в исходный репозиторий с заголовком: Lab<Номер лабораторной>: — Фамилия Имя Группа.
- Пожалуйста, используйте команды git для работы с github. Используйте
git add/commit/push
, исключайте ненужные файлы в.gitignore
- После запроса на слияние вашей ветки с основной вам будет предоставлен автоматический отчёт-ответ с анализом кода и вашего отчёта.
- Вне зависимости от полученного автоматического анализа конечное решение стоит за преподавателем.
- Если всё в порядке, то лабораторная принята. При обнаружении ошибок в лабораторной я укажу на них лично и попрошу исправить.