Преобразование thenApply в Java
Когда первый шаг вернул значение, часто нужно
преобразовать его без блокировки главного потока.
Метод thenApply принимает Function<T, U>
и строит CompletableFuture<U>. Колбэк
выполнится в том же потоке, который завершил
предыдущий этап, если не указать
thenApplyAsync.
Цепочка читается сверху вниз: загрузили текст, посчитали длину, отформатировали вывод:
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) {
String report = CompletableFuture
.supplyAsync(() -> " report ")
.thenApply(String::trim)
.thenApply(String::toUpperCase)
.thenApply(s -> "len=" + s.length())
.join();
System.out.println(report);
}
}
Каждый thenApply стартует только после
успешного завершения предыдущего звена. Если
где-то вылетело исключение, следующие
thenApply не вызываются, пока ошибку
не обработают exceptionally или
handle.
Вариант thenApplyAsync снова уходит в
общий пул или в переданный Executor.
Его берут, когда преобразование тяжёлое и не
должно задерживать поток, который закрыл
сетевой ответ:
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) {
CompletableFuture<Integer> parsed =
CompletableFuture
.supplyAsync(() -> "144")
.thenApplyAsync(Integer::parseInt);
System.out.println(parsed.join());
}
}
Из supplyAsync(() -> 7) получите квадрат и удвоенное значение
ещё одним thenApply. Выведите
join().