Файл: Практикум для студентов, обучающихся по направлению подготовки 09. 03. 04 Программная инженерия.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 30.11.2023

Просмотров: 172

Скачиваний: 2

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ
РОССИЙСКОЙ ФЕДЕРАЦИИ
МИРЭА – РОССИЙСКИЙ ТЕХНОЛОГИЧЕСКИЙ УНИВЕРСИТЕТ
Н.В. СТРОГАНКОВА, К.В. КАСЬЯНЕНКО, А.В. ХОЗЯИНОВ,
О.В. СОБОЛЕВ
ШАБЛОНЫ ПРОГРАММНЫХ ПЛАТФОРМ
ЯЗЫКА JAVA
Практикум для студентов, обучающихся по направлению подготовки
09.03.04 «Программная инженерия»
Москва – 2021

УДК 532.78:548.5
ББК 22.317
И20
Строганкова Н.В. Шаблоны программных платформ языка Java [Электронный ресурс]: практикум / Строганкова Н.В., Касьяненко К.В., Хозяинов А.В., Соболев О.В.– М.:
МИРЭА – Российский технологический университет (РТУ МИРЭА), 2021. – 1 электрон. опт. диск (CD-ROM).
Разработан в помощь студентам, выполняющим практические работы по дисциплине «Шаблоны программных платформ языка Java». В состав практикума входят: использование шаблонов проектирования в клиент-серверных приложениях.
Предназначено для студентов бакалавриата 2 курса направления подготовки
09.03.04 «Программная инженерия».
В состав практикума входят: цель работы; задачи для достижения поставленной цели; описание выполнения практической работы; ожидаемые результаты и форма их представления к защите.
Практикум издается в авторской редакции.
Авторский коллектив: Строганкова Наталья Владимировна, Касьяненко Константин
Владимирович, Хозяинов Артем Владимирович, Соболев Олег Вадимович.
Рецензент:
Петров Андрей Борисович, доктор технических наук, профессор кафедры корпоративных информационных систем РТУ МИРЭА
Минимальный системные требования:
Поддерживаемые ОС: Windows 2000 и выше.
Память: ОЗУ 256МБ.
Жесткий диск: 120 Мб.
Устройства ввода: клавиатура, мышь, скрин.
Дополнительные программные средства: Программа Adobe Reader.
Подписано к использованию по решению Редакционно-издательского совета МИРЭА – Российского технологического университета от ___ _____________ 2021 г.
Объем: ___ Мб
Тираж 10
ISBN _____________________
© Н.В. Строганкова, К.В. Касьяненко,
А.В. Хозяинов, О.В. Соболев, 2021
© МИРЭА – Российский технологический университет, 2021

СОДЕРЖАНИЕ
ВВЕДЕНИЕ ........................................................................................................ 4 1. ПРАКТИЧЕСКАЯ РАБОТА № 1 .................................................................. 5 2. ПРАКТИЧЕСКАЯ РАБОТА № 2 ................................................................ 10 3. ПРАКТИЧЕСКАЯ РАБОТА № 3 ................................................................ 15 4. ПРАКТИЧЕСКАЯ РАБОТА № 4 ................................................................ 20 5. ПРАКТИЧЕСКАЯ РАБОТА № 5 ................................................................ 24 6. ПРАКТИЧЕСКАЯ РАБОТА № 6 ................................................................ 26 7. ПРАКТИЧЕСКАЯ РАБОТА № 7 ................................................................ 29 8. ПРАКТИЧЕСКАЯ РАБОТА № 8 ................................................................ 33 9. ПРАКТИЧЕСКАЯ РАБОТА № 9 ................................................................ 39 10. ПРАКТИЧЕСКАЯ РАБОТА № 10 ............................................................ 44 11. ПРАКТИЧЕСКАЯ РАБОТА № 11 ............................................................ 52 12. ПРАКТИЧЕСКАЯ РАБОТА № 12 ............................................................ 53 13. ПРАКТИЧЕСКАЯ РАБОТА № 13 ............................................................ 55 14. ПРАКТИЧЕСКАЯ РАБОТА № 14 ............................................................ 57 15. ПРАКТИЧЕСКАЯ РАБОТА № 15 ............................................................ 61 16. ПРАКТИЧЕСКАЯ РАБОТА № 16 ............................................................ 67 17. ПРАКТИЧЕСКАЯ РАБОТА № 17 ............................................................ 71 18. ПРАКТИЧЕСКАЯ РАБОТА № 18 ............................................................ 73 19. ПРАКТИЧЕСКАЯ РАБОТА № 19 ............................................................ 77 20. ПРАКТИЧЕСКАЯ РАБОТА № 20 ............................................................ 80 21. ПРАКТИЧЕСКАЯ РАБОТА № 21 ............................................................ 83 22. ПРАКТИЧЕСКАЯ РАБОТА № 22 ............................................................ 85 23. ПРАКТИЧЕСКАЯ РАБОТА № 23 ............................................................ 86 24. ПРАКТИЧЕСКАЯ РАБОТА № 24 ............................................................ 90 25. ОПИСАНИЕ ВЫПОЛНЕНИЯ РАБОТ ..................................................... 94 26. ЗАЩИТА ПРАКТИЧЕСКИХ РАБОТ ....................................................... 95
ПЕРЕЧЕНЬ СОКРАЩЕНИЙ ........................................................................... 96
БИБЛИОГРАФИЧЕСКИЙ СПИСОК ............................................................. 97


ВВЕДЕНИЕ
Данный практикум разработан к практическим работам в рамках дисциплины «Шаблоны программных платформ языка Java» для студентов- бакалавров направления 09.03.04 «Программная инженерия».
Цель курса:
– ознакомление студентов с основными технологиями, необходимыми для создания клиент-серверных приложений;
– изучение фреймворка Spring и работы с ним;
– предоставление теоретической базы для выполнения практических работ.
Данный практикум позволяет на практике разобраться с шаблонами проектирования, использованием шаблонов проектирования в клиент- серверных приложениях. В качестве основного языка программирования выбран язык Java. Также в практических работах будет использоваться фреймворк Spring, ORM библиотека Hibernate.
Практикум разработан к 24 практическим работам, в результате выполнения которых студенты смогут овладеть навыками использования шаблонов проектирования на языке Java. Каждая практическая работа рассчитана на выполнение одним студентом. Некоторые практические работы содержат варианты заданий, которые нужно выбрать в соответствие с порядковым номером студента в группе.

1. ПРАКТИЧЕСКАЯ РАБОТА № 1
Цель работы
Знакомство со встроенными функциональными интерфейсами Java.
Возможности Java 8. Лямбда-выражения. Области действия, замыкания.
Предикаты. Функции. Компараторы.
1.1. Теоретическая часть
Версия Java 8 привнесла огромные изменения в язык, и самым важным является появление функциональной парадигмы в Java. Начнем с того, что же такое функциональное программирование.
Наиболее привычным является императивное программирование, в котором программирование происходит путем описания последовательности инструкций, идущих друг за другом, которые требуется выполнить для достижения требуемого результата. Но также существует декларативное
программирование, в котором описываются не действия для получения результата, а сам результат – программист описывает только требования, которым должен удовлетворять результат. Самым простым примером декларативного программирования является использование языка SQL: select * from users where age > 20;
Функциональное программирование является подтипом декларативного программирования. Оно основано на использовании функций как основных строительных блоков построения приложения. В Java функциональное программирование, в первую очередь, реализовано с использованием функциональных интерфейсов. Функциональный интерфейс – интерфейс с одним и только одним абстрактным методом. Они помечаются аннотацией
FunctionalInterface, при помощи которой компилятор не допустит интерфейсы с более чем одним абстрактным методом.
@FunctionalInterface public interface Summator {
T sum(T elem1, T elem2);


}
Если в каком-то методе функциональный интерфейс передан как параметр, то вместо его реализации можно использовать лямбда-функцию, что заметно упрощает код, делает его более читаемым.
Лямбда функция – блок кода, описывающий функцию интерфейса, некий аналог анонимного класса, только для функциональных интерфейсов.
Ниже приведен пример реализации интерфейса Summator с использованием лямбды:
Summator summator = (a, b) -> a + b;
Однако, если будет использоваться внешний объект в лямбда выражении, то в таком случае ссылка должна быть или final или effectively final (может не помечаться как final, но обязана не изменяться (не должно нигде происходить присвоения ссылки новому значению)):
Integer c = 40;
Summator summator = (a, b) -> a + b + c;
System.out.println(summator.sum(1, 3));
При этом, если попытаться изменить значение переменной c, то получим ошибку:
Integer c = 40;
Summator summator = (a, b) -> a + b + c; c = 11;
System.out.println(summator.sum(1, 3));
Ошибка: java: local variables referenced from a lambda expression must be final or effectively final
В Java 8 было добавлено большое количество стандартных функциональных интерфейсов. Например, Predicate, получающий на вход какой-то объект и возвращающий boolean:
@FunctionalInterface public interface Predicate { boolean test(T t);
}

Predicate можно передавать как параметр в какие-то методы, например, для фильтрации объектов. Еще одним стандартным интерфейсов является
Function:
@FunctionalInterface public interface Function {
R apply(T t);
}
Отлично подойдет для преобразования одного объекта в другой.
Comparator используется для сравнения двух объектов одного типа:
@FunctionalInterface public interface Comparator { int compare(T o1, T o2);
}
Еще одно удобство использования функциональных интерфейсов – возможность передачи метода или конструктора в качестве аргумента:
Summator sum = Integer::sum;
Integer result = sum.sum(1,2);
System.out.println(result);
Отдельно в вакууме стандартные функциональные интерфейсы не кажутся очень полезными, но их использование для создания каких-то других классов с дополнительной логикой значительно упрощает код. Удобство использования стандартных функциональных интерфейсов вы увидите в следующей практической работе – «Работа со Stream API в Java 8».
1.2. Варианты индивидуального задания
1) Имплементировать интерфейс Function, получающий на вход массив чисел (каждое число может быть значением от 0 до 9) и возвращающий строку
– наименьшее число, которое возможно собрать из данных чисел, используя цифры только один раз (игнорируя дубликаты). Пример: minValue ({1, 3, 1}) ==> return (13)


2) Имплементировать интерфейс Function, получающий на вход массив студентов и возвращающий сгруппированных по группе студентов
(
Map>
).
3) Имплементировать интерфейс Function, получающий на вход массив строк и возвращающий массив отзеркаленных строк.
4) Имплементировать интерфейс Function, получающий на вход пару чисел и возвращающий наибольший общий делитель.
5) Имплементировать интерфейс Comparator, сравнивающий две строки по сумме всех чисел, представленных в строке.
6) Имплементировать интерфейс Comparator, сравнивающий двух студентов по набранным за семестр баллов.
7) Имплементировать интерфейс Comparator, сравнивающий два числа по модулю.
8) Имплементировать интерфейс Comparator, сравнивающий два массива с одинаковыми типами элементов по количеству элементов в данных массивах.
9) Имплементировать интерфейс Predicate, определяющий, является ли данная строка PIN-кодом (содержит ровно 4 цифры или 6 цифр).
10) Имплементировать интерфейс Predicate, определяющий, является ли данная строка email-адресом, используя регулярное выражение.
11) Имплементировать интерфейс Predicate, определяющий, является ли число степенью двойки.
12) Имплементировать интерфейс Predicate, определяющий, содержит ли массив студентов студента с максимальным количеством баллов
(максимальное значение – 100).
13) Имплементировать интерфейс Consumer, принимающий на вход строку, заменяющий каждый третий символ строки на такой же символ в верхнем регистре и выводящий в консоль результат.

14) Имплементировать интерфейс Consumer, принимающий на вход массив строк и выводящий в консоль строку с наибольшим количеством уникальных символов.
15) Имплементировать интерфейс Consumer, принимающий на вход массив чисел и выводящий в консоль в порядке возрастания.

2. ПРАКТИЧЕСКАЯ РАБОТА № 2
Цель работы
Работа со Stream API в Java 8.
2.1. Теоретическая часть
В Java 8 был добавлен новый способ взаимодействия с некими коллекциями объектов – Stream API. В первую очередь, Stream стоит воспринимать именно как поток неких объектов, который можно так или иначе изменять. Особенности Stream:
– потоки не являются структурой данных, не хранит элементы;
– потоки не изменяют начальную структуру данных, а лишь возвращают результат в виде потока новых данных;
– нетерминальные операции в потоках являются «ленивыми», то есть запускаются только по требованию при запуске терминальных операций.
Нетерминальные операции, или промежуточные – те операции, которые возвращают трансформированный поток данных, терминальные операции возвращают конечный результат и фактически завершают поток. Пример создания потока:
Stream stream = Stream.of(1, 2, 3);
Ниже перечислены некоторые виды нетерминальных и терминальных операций с их описанием.
Нетерминальные операции:
– sorted() – сортирует поток. Может быть передана реализация интерфейса Comparator для сортировки;
– filter(Predicate super T> predicate ) – фильтрует элементы потока в соответствии с реализацией Predicate;
– map(Function super T, ? extends R> mapper) – трансформирует объекты потока;
– distinct() – убирает дубликаты;
– skip(long n) – пропускает первые n элементов;


Stream flatMap(Function super T, ? extends Stream extends
R>> mapper) – превращает один объект в поток, затем все потоки конкатенирует.
Терминальные операции:
– forEach(Consumer super T> action) – выполняет какую-то операцию для каждого элемента;
– reduce(BinaryOperator accumulator) – аккумулирует все объекты в один, по очереди применяя ее к парам из элементов, затем также к результату операции и следующему элементу, и так далее по всем элементам, получая в итоге один результат. Самый простой пример для понимания – нахождение суммы:
Optional sum = Stream.of(1, 2, 3).reduce((a, b) -> a + b);
– min(Comparator super T> comparator) – находит минимальный элемент с использованием Comparator;
– count() – возвращает количество элементов;
– findFirst() – возвращает первый элемент.
Конечно же, Stream имеет много больше различных операций, здесь перечислены только самые базовые операции.
В Java 8 потоки не могут быть использованы повторно. После вызова любого терминального метода поток завершается:
Stream stream = Stream.of(1, 2, 3); stream.forEach((a) -> {}); stream.findFirst();
Ошибка:
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
Пример использования потоков
Например, дан список строк, нужно отфильтровать все строки длиной больше 10 и отсортировать по длине строки. Для начала следует создать список, заполнить его данными и получить из него поток:

List input = new ArrayList<>(); input.add("My"); input.add("Authors"); input.add("Haruki Murakami"); input.add("Franz Kafka"); input.add("Charles Bukowski");
Stream stream = input.stream();
Затем отфильтровать, отсортировать по длине и вывести результат в консоль: stream.filter(str -> str.length() > 10)
.sorted(Comparator.comparingInt(String::length))
.forEach(System.out::println);
В итоге получим такой результат (рисунок 1):
Рисунок 1 – Результат выполнения примера использования потоков
Для лучшего изучения потоков и функционального программирования в Java рекомендуется прочитать книгу «Functional Interfaces in Java»
Ralph Lecessi
(https://www.amazon.com/Functional-Interfaces-Java-
Fundamentals-Examples-ebook/dp/B07NRHQSCW).
2.2. Задание
В ходе выполнения практической работы должно быть реализовано:
1) класс Human (int age, String firstName, String lastName, LocalDate birthDate, int weight);
2) приложение, которое создает список из объектов класса Human, а затем производит действия в соответствии с вариантом индивидуального задания (список после каждого этапа должен выводиться в консоль).