JavaRush /Java блог /Random /Кофе-брейк #265. Асинхронное программирование на Java. По...

Кофе-брейк #265. Асинхронное программирование на Java. Понимание метода max из Java Stream API

Статья из группы Random

Асинхронное программирование на Java

Источник: Medium В этом руководстве рассмотрены основы применения асинхронного программирования на Java. Кофе-брейк #265. Асинхронное программирование на Java. Понимание метода max из Java Stream API - 1Вы когда-нибудь задумывались, как компьютеры справляются с несколькими задачами одновременно, не замедляя свою работу? В этом помогает асинхронное программирование. Благодаря ему компьютер выполняет задачи, не дожидаясь завершения каждой из них, прежде чем начинать следующую. Ранее в Java все задачи выполнялись последовательно, одна за другой. При асинхронном программировании работа больше похожа на одновременное приготовление нескольких блюд.

Асинхронные способы работы в Java

  1. Callbacks и Callback Hell. В Java обратные вызовы (Callbacks) подобны напоминаниям. То есть, вы как бы устанавливаете на кухне таймер, который сообщит вам, когда ваше печенье будет готово. Однако слишком большое количество обратных вызовов может привести к путанице, что приведет к так называемому “аду обратных вызовов” (Callback Hell), когда становится трудно отслеживать, что происходит.
  2. CompletableFuture в Java. Начиная с версии 8 в языке Java представлено расширение под названием CompletableFuture, которое делает асинхронное программирование более управляемым. Оно похоже на помощника, который выполняет различные задачи и сообщает вам, когда каждая из них выполнена. Благодаря ему мы можем избежать путаницы, связанной с Callback Hell.
  3. Использование ExecutorService для асинхронных задач. Представьте ExecutorService как команду поваров. Вы даете им задания (или рецепты), и они работают над ними самостоятельно. Таким образом, вам не придется ждать завершения одной задачи, прежде чем приступить к другой.

Рекомендации и шаблоны в асинхронном программировании

  1. Обрабатывайте ошибки в асинхронном коде. Как и в любом кулинарном проекте, все может пойти не так, как планировалось. Обработка ошибок в асинхронном программировании Java предполагает готовность к неожиданностям, например, наличие резервного плана на случай, если рецепт окажется неверным.
  2. Как избежать появления распространенных ошибок. При приготовлении пищи или кодировании могут случаться ошибки. В асинхронном программировании мы можем избежать распространенных ошибок, делая наш код простым для понимания и обслуживания. Это все равно что содержать кухню в чистоте и порядке. Вот пример:

package Java;

import java.util.concurrent.CompletableFuture;

public class AsyncExp {

static String fetchData(String from){

try {

Thread.sleep(2000);

} catch (Exception e) {

e.printStackTrace();

}

return " Data Comming From :"+from;

}

public static void main(String[] args) {

// Получение данных из двух разных источников

CompletableFuture<String> data1 = CompletableFuture.supplyAsync(()-> fetchData("Wifi 1 5G"));

CompletableFuture<String> data2 = CompletableFuture.supplyAsync(()-> fetchData("Wifi 2 JioFiber"));

CompletableFuture<Void> runAtOneTime = CompletableFuture.allOf(data1, data2);

runAtOneTime.thenRun(()-> {

try {

String dataDevice1 = data1.join(); //

String dataDevice2 = data2.join();

System.out.println("DataDevice1:: "+dataDevice1);

System.out.println("DataDevice2:: "+dataDevice2);

} catch (Exception e) {

e.printStackTrace();

}

});

System.out.println("Completing other tasks till getting data devices ::::::");

try {

Thread.sleep(5000); // ожидание завершения асинхронных задач

} catch (Exception e) {

e.printStackTrace();

}

}

}

Варианты использования асинхронного программирования

  • Веб-разработка. При создании веб-сайтов или веб-приложений на Java асинхронное программирование помогает обрабатывать несколько запросов одновременно. Это все равно, что обслуживать в ресторане множество клиентов, не заставляя каждого из них долго ждать.
  • Асинхронные операции ввода-вывода. Операции ввода-вывода включают чтение или запись данных. Асинхронное программирование на Java похоже на возможность читать книгу, ожидая окончания стирки в стиральной машине. То есть, вам не нужно все время смотреть на нее. Работа продолжается без вас.

Java Stream API: понимание метода max

Источник: Medium Благодаря этой публикации вы научитесь применять в своей работе метод max из пакета java.util.stream и узнаете, как это делать с максимальной эффективностью. Stream API, представленный в Java 8, позволяет выполнять функциональные операции с потоками элементов, предоставляя новый и эффективный способ обработки коллекций в Java. Метод max является частью этого API и используется для поиска максимального элемента в потоке на основе заданного компаратора.

Обзор метода max

Синтаксис: Optional<T> max(Comparator<? super T> comparator). Определяет максимальный элемент потока согласно указанному компаратору. Optional<T> — контейнер, который может содержать или не содержать ненулевое значение. Comparator — функциональный интерфейс, необходимый для сравнения элементов в потоке. Метод max определен в интерфейсе Stream<T> пакета java.util.stream. Этот интерфейс является ключевым компонентом возможностей функционального программирования Java, представленных в Java 8.

Что такое компаратор

Как уже сообщалось, Comparator — это функциональный интерфейс, используемый для сравнения двух объектов.

package java.util;

@FunctionalInterface
public interface Comparator<T> {

    int compare(T o1, T o2);

    boolean equals(Object obj);

    // Статический метод naturalOrder
    static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
        return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
    }

    // Другие методы по умолчанию и статические методы, такие как Reversed, thenComparing и др.
}
Компаратор помечен аннотацией @FunctionalInterface, которая означает, что он предназначен для использования с одним абстрактным методом. Это делает его пригодным для использования с лямбда-выражениями и ссылками на методы в Java 8 и более поздних версиях.

Пример использования метода max


// Импорт необходимых классов

// Создание списка целых чисел
List<Integer> numbers = Arrays.asList(3, 51, 1, 41, 12);

// Использование API потока для обработки списка
// Метод max находит максимальный элемент, используя компаратор естественного порядка
Optional<Integer> maxNumber = numbers.stream().max(Comparator.naturalOrder());

// Использование ifPresent для безопасного доступа к максимальному значению, если оно присутствует 
// ifPresent — это метод класса Optional  
// System.out::println — это ссылка на метод, используемый для печати значения
 maxNumber.ifPresent(System.out::println); // Выводит максимальное число

Применение пользовательского компаратора


// Создание списка чисел (как объектов Integer)
List<Integer> numbers = Arrays.asList(10, 20, 5, 40, 30);

// Использование API потока для обработки списка 
// Использование лямбда-выражения для компаратора для поиска наибольшего числа
Optional<Integer> largestNumber = numbers.stream()
            .max((n1, n2) -> n1.compareTo(n2));

// Использование ifPresent для безопасного доступа к наибольшему числу, если оно присутствует 
// ifPresent — это метод класса Optional
// System.out::println — это ссылка на метод, используемый для печати значения
largestNumber.ifPresent(System.out::println); // Выводит наибольшее число
Рекомендация: Всегда обрабатывайте Optional типа возвращаемого значения соответствующим образом, чтобы избежать ошибки NoSuchElementException.

Заключение

Метод max представляет собой мощный и универсальный инструмент в Stream API, который позволяет разработчику эффективно определять максимальный элемент в коллекции.
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ