Современный язык Java. Лямбда-выражения, потоки и функциональное программирование
Book information
Description
Преимущество современных приложений — в передовых решениях, включающих микросервисы, реактивные архитектуры и потоковую обработку данных. Лямбда-выражения, потоки данных и долгожданная система модулей платформы Java значительно упрощают их реализацию. Пришло время повысить свою квалификацию и встретить любой вызов во всеоружии! Книга поможет вам овладеть новыми возможностями современных дополнений, таких как API Streams и система модулей платформы Java. Откройте для себя новые подходы к конкурентности и узнайте, как концепции функциональности улучшают работу с кодом. В этой книге: • Новые возможности Java. • Потоковые данные и реактивное программирование. • Система модулей платформы Java. Иллюстрация на обложке Об авторах Благодарности Рауль-Габриэль Урма Марио Фуско Алан Майкрофт Предисловие Об этой книге Структура издания О коде Форум для обсуждения книги От издательства Часть I. Основы Глава 1. Java 8, 9, 10 и 11: что происходит? 1.1. Итак, о чем вообще речь? 1.2. Почему Java все еще меняется 1.2.1. Место языка Java в экосистеме языков программирования 1.2.2. Потоковая обработка 1.2.3. Передача кода в методы и параметризация поведения 1.2.4. Параллелизм и разделяемые изменяемые данные 1.2.5. Язык Java должен развиваться 1.3. Функции в Java 1.3.1. Методы и лямбда-выражения как полноправные граждане 1.3.2. Передача кода: пример 1.3.3. От передачи методов к лямбда-выражениям 1.4. Потоки данных 1.4.1. Многопоточность — трудная задача 1.5. Методы с реализацией по умолчанию и модули Java 1.6. Другие удачные идеи, заимствованные из функционального программирования Резюме Глава 2. Передача кода и параметризация поведения 2.1. Как адаптироваться к меняющимся требованиям 2.1.1. Первая попытка: фильтрация зеленых яблок 2.1.2. Вторая попытка: параметризация цвета 2.1.3. Третья попытка: фильтрация по всем возможным атрибутам 2.2. Параметризация поведения 2.2.1. Четвертая попытка: фильтрация по абстрактному критерию 2.3. Делаем код лаконичнее 2.3.1. Анонимные классы 2.3.2. Пятая попытка: использование анонимного класса 2.3.3. Шестая попытка: использование лямбда-выражения 2.3.4. Седьмая попытка: абстрагирование по типу значений списка 2.4. Примеры из практики 2.4.1. Сортировка с помощью интерфейса Comparator 2.4.2. Выполнение блока кода с помощью интерфейса Runnable 2.4.3. Возвращение результатов выполнения задачи с помощью интерфейса Callable 2.4.4. Обработка событий графического интерфейса Резюме Глава 3. Лямбда-выражения 3.1. Главное о лямбда-выражениях 3.2. Где и как использовать лямбда-выражения 3.2.1. Функциональный интерфейс 3.2.2. Функциональные дескрипторы 3.3. Практическое использование лямбда-выражений: паттерн охватывающего выполнения 3.3.1. Шаг 1: вспоминаем параметризацию поведения 3.3.2. Шаг 2: используем функциональный интерфейс для передачи поведения 3.3.3. Шаг 3: выполняем нужный вариант поведения! 3.3.4. Шаг 4: передаем лямбда-выражения 3.4. Использование функциональных интерфейсов 3.4.1. Интерфейс Predicate 3.4.2. Интерфейс Consumer 3.4.3. Интерфейс Function 3.5. Проверка типов, вывод типов и ограничения 3.5.1. Проверка типов 3.5.2. То же лямбда-выражение, другие функциональные интерфейсы 3.5.3. Вывод типов 3.5.4. Использование локальных переменных 3.6. Ссылки на методы 3.6.1. В общих чертах 3.6.2. Ссылки на конструкторы 3.7. Практическое использование лямбда-выражений и ссылок на методы 3.7.1. Шаг 1: передаем код 3.7.2. Шаг 2: используем анонимный класс 3.7.3. Шаг 3: используем лямбда-выражения 3.7.4. Шаг 4: используем ссылки на методы 3.8. Методы, удобные для композиции лямбда-выражений 3.8.1. Композиция объектов Comparator 3.8.2. Композиция предикатов 3.8.3. Композиция функций 3.9. Схожие математические идеи 3.9.1. Интегрирование 3.9.2. Переводим на язык лямбда-выражений Java 8 Резюме Часть II. Функциональное программирование с помощью потоков Глава 4. Знакомство с потоками данных 4.1. Что такое потоки данных 4.2. Знакомимся с потоками данных 4.3. Потоки данных и коллекции 4.3.1. Строго однократный проход 4.3.2. Внутренняя и внешняя итерация 4.4. Потоковые операции 4.4.1. Промежуточные операции 4.4.2. Завершающие операции 4.4.3. Работа с потоками данных Резюме Глава 5. Работа с потоками данных 5.1. Фильтрация 5.1.1. Фильтрация с помощью предиката 5.1.2. Фильтрация уникальных элементов 5.2. Срез потока данных 5.2.1. Срез с помощью предиката 5.2.2. Усечение потока данных 5.2.3. Пропуск элементов 5.3. Отображение 5.3.1. Применение функции к каждому из элементов потока данных 5.3.2. Схлопывание потоков данных 5.4. Поиск и сопоставление с шаблоном 5.4.1. Проверяем, удовлетворяет ли предикату хоть один элемент 5.4.2. Проверяем, удовлетворяют ли предикату все элементы 5.4.3. Поиск элемента в потоке 5.4.4. Поиск первого элемента 5.5. Свертка 5.5.1. Суммирование элементов 5.5.2. Максимум и минимум 5.6. Переходим к практике 5.6.1. Предметная область: трейдеры и транзакции 5.6.2. Решения 5.7. Числовые потоки данных 5.7.1. Версии потоков для простых типов данных 5.7.2. Числовые диапазоны 5.7.3. Применяем числовые потоки данных на практике: пифагоровы тройки 5.8. Создание потоков данных 5.8.1. Создание потока данных из перечня значений 5.8.2. Создание потока данных из объекта, допускающего неопределенное значение 5.8.3. Создание потоков данных из массивов 5.8.4. Создание потоков данных из файлов 5.8.5. Потоки на основе функций: создание бесконечных потоков Резюме Глава 6. Сбор данных с помощью потоков 6.1. Главное о коллекторах 6.1.1. Коллекторы как продвинутые средства свертки 6.1.2. Встроенные коллекторы 6.2. Свертка и вычисление сводных показателей 6.2.1. Поиск максимума и минимума в потоке данных 6.2.2. Вычисление сводных показателей 6.2.3. Объединение строк 6.2.4. Обобщение вычисления сводных показателей с помощью свертки 6.3. Группировка 6.3.1. Дальнейшие операции со сгруппированными элементами 6.3.2. Многоуровневая группировка 6.3.3. Сбор данных в подгруппы 6.4. Секционирование 6.4.1. Преимущества секционирования 6.4.2. Секционирование чисел на простые и составные 6.5. Интерфейс Collector 6.5.1. Разбираемся с объявленными в интерфейсе Collector методами 6.5.2. Собираем все вместе 6.6. Разрабатываем собственный, более производительный коллектор 6.6.1. Деление только на простые числа 6.6.2. Сравнение производительности коллекторов Резюме Глава 7. Параллельная обработка данных и производительность 7.1. Параллельные потоки данных 7.1.1. Превращаем последовательный поток данных в параллельный 7.1.2. Измерение быстродействия потока данных 7.1.3. Правильное применение параллельных потоков данных 7.1.4. Эффективное использование параллельных потоков данных 7.2. Фреймворк ветвления-объединения 7.2.1. Работа с классом RecursiveTask 7.2.2. Рекомендуемые практики применения фреймворка ветвления-объединения 7.2.3. Перехват работы 7.3. Интерфейс Spliterator 7.3.1. Процесс разбиения 7.3.2. Реализация собственного сплитератора Резюме Часть III. Эффективное программирование с помощью потоков и лямбда-выражений Глава 8. Расширения Collection API 8.1. Фабрики коллекций 8.1.1. Фабрика списков 8.1.2. Фабрика множеств 8.1.3. Фабрики ассоциативных массивов 8.2. Работа со списками и множествами 8.2.1. Метод removeIf 8.2.2. Метод replaceAll 8.3. Работа с ассоциативными массивами 8.3.1. Метод forEach 8.3.2. Сортировка 8.3.3. Метод getOrDefault 8.3.4. Паттерны вычисления 8.3.5. Паттерны удаления 8.3.6. Способы замены элементов 8.3.7. Метод merge 8.4. Усовершенствованный класс ConcurrentHashMap 8.4.1. Свертка и поиск 8.4.2. Счетчики 8.4.3. Представление в виде множества Резюме Глава 9. Рефакторинг, тестирование и отладка 9.1. Рефакторинг с целью повышения удобочитаемости и гибкости кода 9.1.1. Повышаем удобочитаемость кода 9.1.2. Из анонимных классов — в лямбда-выражения 9.1.3. Из лямбда-выражений — в ссылки на методы 9.1.4. От императивной обработки данных до потоков 9.1.5. Повышаем гибкость кода 9.2. Рефакторинг объектно-ориентированных паттернов проектирования с помощью лямбда-выражений 9.2.1. Стратегия 9.2.2. Шаблонный метод 9.2.3. Наблюдатель 9.2.4. Цепочка обязанностей 9.2.5. Фабрика 9.3. Тестирование лямбда-выражений 9.3.1. Тестирование поведения видимого лямбда-выражения 9.3.2. Делаем упор на поведение метода, использующего лямбда-выражение 9.3.3. Разносим сложные лямбда-выражения по отдельным методам 9.3.4. Тестирование функций высшего порядка 9.4. Отладка 9.4.1. Изучаем трассу вызовов в стеке 9.4.2. Журналирование информации Резюме Глава 10. Предметно-ориентированные языки и лямбда-выражения 10.1. Специальный язык для конкретной предметной области 10.1.1. За и против предметно-ориентированных языков 10.1.2. Доступные на JVM решения, подходящие для создания DSL 10.2. Малые DSL в современных API Java 10.2.1. Stream API как DSL для работы с коллекциями 10.2.2. Коллекторы как предметно-ориентированный язык агрегирования данных 10.3. Паттерны и методики создания DSL на языке Java 10.3.1. Связывание методов цепочкой 10.3.2. Вложенные функции 10.3.3. Задание последовательности функций с помощью лямбда-выражений 10.3.4. Собираем все воедино 10.3.5. Использование ссылок на методы в DSL 10.4. Реальные примеры DSL Java 8 10.4.1. jOOQ 10.4.2. Cucumber 10.4.3. Фреймворк Spring Integration Резюме Часть IV. Java на каждый день 11 Класс Optional как лучшая альтернатива null 11.1. Как смоделировать отсутствие значения 11.1.1. Снижение количества исключений NullPointerException с помощью проверки на безопасность 11.1.2. Проблемы, возникающие с null 11.1.3. Альтернативы null в других языках программирования 11.2. Знакомство с классом Optional 11.3. Паттерны для внедрения в базу кода опционалов 11.3.1. Создание объектов Optional 11.3.2. Извлечение и преобразование значений опционалов с помощью метода map 11.3.3. Связывание цепочкой объектов Optional с помощью метода flatMap 11.3.4. Операции над потоком опционалов 11.3.5. Действия по умолчанию и распаковка опционалов 11.3.6. Сочетание двух опционалов 11.3.7. Отбрасывание определенных значений с помощью метода filter 11.4. Примеры использования опционалов на практике 11.4.1. Обертывание потенциально пустого значения в опционал 11.4.2. Исключения или опционалы? 11.4.3. Версии опционалов для простых типов данных и почему их лучше не использовать 11.4.4. Собираем все воедино Резюме 12 Новый API для работы с датой и временем 12.1. Классы LocalDate, LocalTime, LocalDateTime, Instant, Duration и Period 12.1.1. Работа с классами LocalDate и LocalTime 12.1.2. Сочетание даты и времени 12.1.3. Класс Instant: дата и время для компьютеров 12.1.4. Описание продолжительности и промежутков времени 12.2. Операции над датами, синтаксический разбор и форматирование дат 12.2.1. Работа с классом TemporalAdjusters 12.2.2. Вывод в консоль и синтаксический разбор объектов даты/времени 12.3. Различные часовые пояса и системы летоисчисления 12.3.1. Использование часовых поясов 12.3.2. Фиксированное смещение от UTC/времени по Гринвичу 12.3.3. Использование альтернативных систем летоисчисления Резюме 13 Методы с реализацией по умолчанию 13.1. Эволюция API 13.1.1. Версия 1 API 13.1.2. Версия 2 API 13.2. Коротко о методах с реализацией по умолчанию 13.3. Примеры использования методов с реализацией по умолчанию 13.3.1. Необязательные методы 13.3.2. Множественное наследование поведения 13.4. Правила разрешения конфликтов 13.4.1. Три важных правила разрешения неоднозначностей 13.4.2. Преимущество — у самого конкретного интерфейса из числа содержащих реализацию по умолчанию 13.4.3. Конфликты и разрешение неоднозначностей явным образом 13.4.4. Проблема ромбовидного наследования Резюме 14 Система модулей Java 14.1. Движущая сила появления системы модулей Java: размышления о ПО 14.1.1. Разделение ответственности 14.1.2. Скрытие информации 14.1.3. Программное обеспечение на языке Java 14.2. Причины создания системы модулей Java 14.2.1. Ограничения модульной организации 14.2.2. Монолитный JDK 14.2.3. Сравнение с OSGi 14.3. Модули Java: общая картина 14.4. Разработка приложения с помощью системы модулей Java 14.4.1. Подготовка приложения 14.4.2. Мелкоблочная и крупноблочная модуляризация 14.4.3. Основы системы модулей Java 14.5. Работа с несколькими модулями 14.5.1. Выражение exports 14.5.1. Выражение requires 14.5.3. Именование 14.6. Компиляция и компоновка 14.7. Автоматические модули 14.8. Объявление модуля и выражения 14.8.1. Выражение requires 14.8.2. Выражение exports 14.8.3. Выражение requires transitive 14.8.4. Выражение exports ... to 14.8.5. Выражения open и opens 14.8.6. uses и provides 14.9. Пример побольше и дополнительные источники информации Резюме Часть V. Расширенная конкурентность в языке Java 15 Основные концепции класса CompletableFuture и реактивное программирование 15.1. Эволюция поддержки конкурентности в Java 15.1.1. Потоки выполнения и высокоуровневые абстракции 15.1.2. Исполнители и пулы потоков выполнения 15.1.3. Другие абстракции потоков выполнения: (не) вложенность в вызовы методов 15.1.4. Что нам нужно от потоков выполнения 15.2. Синхронные и асинхронные API 15.2.1. Фьючерсный API 15.2.2. Реактивный API 15.2.3. Приостановка и другие блокирующие операции вредны 15.2.4. Смотрим правде в глаза 15.2.5. Исключения и асинхронные API 15.3. Модель блоков и каналов 15.4. Реализация конкурентности с помощью класса CompletableFuture и комбинаторов 15.5. Публикация/подписка и реактивное программирование 15.5.1. Пример использования для суммирования двух потоков сообщений 15.5.2. Противодавление 15.5.3. Простой вариант реализации противодавления на практике 15.6. Реактивные системы и реактивное программирование Резюме 16 Класс CompletableFuture: композиция асинхронных компонентов 16.1. Простые применения фьючерсов 16.1.1. Разбираемся в работе фьючерсов и их ограничениях 16.1.2. Построение асинхронного приложения с помощью завершаемых фьючерсов 16.2. Реализация асинхронного API 16.2.1. Преобразование синхронного метода в асинхронный 16.2.2. Обработка ошибок 16.3. Делаем код неблокирующим 16.3.1. Распараллеливание запросов с помощью параллельного потока данных 16.3.2. Выполнение асинхронных запросов с помощью завершаемых фьючерсов 16.3.3. Поиск лучше масштабируемого решения 16.3.4. Пользовательский исполнитель 16.4. Конвейерная организация асинхронных задач 16.4.1. Реализация сервиса скидок 16.4.2. Использование скидочного сервиса 16.4.3. Композиция синхронных и асинхронных операций 16.4.4. Сочетание двух завершаемых фьючерсов: зависимого и независимого 16.4.5. Сравниваем фьючерсы с завершаемыми фьючерсами 16.4.6. Эффективное использование тайм-аутов 16.5. Реагирование на завершение CompletableFuture 16.5.1. Рефакторинг приложения для поиска наилучшей цены 16.5.2. Собираем все вместе Резюме 17 Реактивное программирование 17.1. Манифест реактивности 17.1.1. Реактивность на прикладном уровне 17.1.2. Реактивность на системном уровне 17.2. Реактивные потоки данных и Flow API 17.2.1. Знакомство с классом Flow 17.2.2. Создаем ваше первое реактивное приложение 17.2.3. Преобразование данных с помощью интерфейса Processor 17.2.4. Почему Java не предоставляет реализации Flow API 17.3. Реактивная библиотека RxJava 17.3.1. Создание и использование наблюдаемых объектов 17.3.2. Преобразование и группировка наблюдаемых объектов Резюме Часть VI. Функциональное программирование и эволюция языка Java 18 Мыслим функционально 18.1. Создание и сопровождение систем 18.1.1. Разделяемые изменяемые данные 18.1.2. Декларативное программирование 18.1.3. Почему функциональное программирование? 18.2. Что такое функциональное программирование 18.2.1. Функциональное программирование на языке Java 18.2.2. Функциональная прозрачность 18.2.3. Объектно-ориентированное и функциональное программирование 18.2.4. Функциональное программирование в действии 18.3. Рекурсия и итерация Резюме 19 Методики функционального программирования 19.1. Повсюду функции 19.1.1. Функции высшего порядка 19.1.2. Каррирование 19.2. Персистентные структуры данных 19.2.1. Деструктивные и функциональные обновления 19.2.2. Другой пример, с деревьями 19.2.3. Функциональный подход 19.3. Отложенное вычисление с помощью потоков данных 19.3.1. Самоопределяющиеся потоки данных 19.3.2. Наш собственный отложенный список 19.4. Сопоставление с шаблоном 19.4.1. Паттерн проектирования «Посетитель» 19.4.2. На помощь приходит сопоставление с шаблоном 19.5. Разное 19.5.1. Кэширование или мемоизация 19.5.2. Что значит «вернуть тот же самый объект»? 19.5.3. Комбинаторы Резюме 20 Смесь ООП и ФП: сравнение Java и Scala 20.1. Введение в Scala 20.1.1. Приложение Hello beer 20.1.2. Основные структуры данных Scala: List, Set, Map, Stream, Tuple и Option 20.2. Функции 20.2.1. Полноправные функции 20.2.2. Анонимные функции и замыкания 20.2.3. Каррирование 20.3. Классы и типажи 20.3.1. Код с классами Scala становится лаконичнее 20.3.2. Типажи Scala и интерфейсы Java Резюме 21 Заключение и дальнейшие перспективы Java 21.1. Обзор возможностей Java 8 21.1.1. Параметризация поведения (лямбда-выражения и ссылки на методы) 21.1.2. Потоки данных 21.1.3. Класс CompletableFuture 21.1.4. Класс Optional 21.1.5. Flow API 21.1.6. Методы с реализацией по умолчанию 21.2. Система модулей Java 9 21.3. Вывод типов локальных переменных в Java 10 21.4. Что ждет Java в будущем? 21.4.1. Вариантность по месту объявления 21.4.2. Сопоставление с шаблоном 21.4.3. Более полнофункциональные формы обобщенных типов 21.4.4. Расширение поддержки неизменяемости 21.4.5. Типы-значения 21.5. Ускорение развития Java 21.6. Заключительное слово Приложения А. Прочие изменения языка A.1. Аннотации A.1.1. Повторяющиеся аннотации A.1.2. Аннотации типов A.2. Обобщенный вывод целевых типов Б. Прочие изменения в библиотеках Б.1. Коллекции Б.1.1. Добавленные методы Б.1.2. Класс Collections Б.1.3. Интерфейс Comparator Б.2. Конкурентность Б.2.1. Пакет Atomic Б.2.2. ConcurrentHashMap Б.3. Массивы Б.3.1. Использование метода parallelSort Б.3.2. Использование методов setAll и parallelSetAll Б.3.3. Использование метода parallelPrefix Б.4. Классы Number и Math Б.4.1. Класс Number Б.4.2. Класс Math Б.5. Класс Files Б.6. Рефлексия Б.7. Класс String В. Параллельное выполнение нескольких операций над потоком данных В.1. Ветвление потока данных В.1.1. Реализация интерфейса Results на основе класса ForkingStreamConsumer В.1.2. Разработка классов ForkingStreamConsumer и BlockingQueueSpliterator В.1.3. Применяем StreamForker на практике В.2. Вопросы производительности Г. Лямбда-выражения и байт-код JVM Г.1. Анонимные классы Г.2. Генерация байт-кода Г.3. Invokedynamic спешит на помощь Г.4. Стратегии генерации кода
Similar books
Modern Java in Action: Lambdas, streams, functional and reactive programming
2018 · PDF
Modern Java in Action: Lambda, streams, functional and reactive programming
2018 · PDF
Гид Java разработчика: проектно-ориентированный подход
2022 · DJVU
Гид Java разработчика: проектно-ориентированный подход
2022 · PDF
Методология научных исследований и прикладной аналитики: Учебник. Изд. 5-е, дополн. и перераб. В 2 т. Т.2: Научные исследования: Мастерство и искусство научного мышления и научной работы / Methodology of Scientific Research and Practical Analytics: A Textbook: Fifth Edition. In two volumes. Vol.2: Scientific research: Art of scientific thinking and scientific work / Méthodologie de la recherche scientifique et de l’analytique appliquée: Manuel: Cinquième édition. En 2 tomes. T.2: Recherches scientifiques: Art de la pensée scientifique et du travail scientifique
2025 · PDF
Методы и понятия философии искусства: практикум : уровень подготовки кадров высшей квалификации: ассиснтурв-стажировка : специальности: 54.09.03 "Искусство дизайна (по видам)", 54.09.02 "Мастерство декоративно-прикладного искусства и народных промыслов (по видам)" : укрупненная группа специальностей: 54.00.00 "Изобразительное и прикладные виды искусств" : квалификация выпускника: "Преподаватель творческих дисциплин в высшей школе. Дизайнер", "Преподаватель творческих дисциплин в высшей школе. Художник декоративно-прикладного искусства" : форма обучения: очная
2022 · PDF
Разработка графического интерфейса пользователя информационной системы с использованием библиотеки QT: учебное пособие для студентов 1 курса направлений подготовки 09.04.02 "Информационные системы и технологии", 27.04.03 "Системный анализ и управление" очной формы обучения, 2 курса направления подготовки 10.05.03 "Информационная безопасность автоматизированных систем" очной формы обучения и 3 курса направления подготовки 09.03.02 "Информационные системы и технологии" очной и заочной форм обучения : учебное электронное издание
2021 · PDF
Археологические культуры Сибири в контексте кросс-культурных контактов в Евразии: к 300-летию первых научных археологических раскопок в Сибири (1722 г.) =: Archaeological Cultures of Siberia in the context of Cross-cultural contacts in Eurasia: dedicated to the 300th anniversary of the first scientific archaeological excavations in Siberia (1722) : материалы Международной археологической конференции молодых исследователей "Археологические культуры Сибири в контексте кросс-культурных контактов в Евразии: к 300-летию первых научных археологических раскопок в Сибири (1722 г.)" (Новосибирск, 21-25 ноября 2022 г.)
2022 · PDF