[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-mnogopotochnost-kakie-osnovnye-metody-est-u-completablefuture":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":21,"progress":22,"seo":23},294,"kakie-osnovnye-metody-est-u-completablefuture",8,"mnogopotochnost","Многопоточность","🔀","Какие основные методы есть у CompletableFuture?","\u003C!-- grade: 5\u002F5 — исчерпывающий обзор с примерами -->\n\nМетоды `CompletableFuture` можно разделить на несколько категорий:\n\n**1. Создание:**\n\n- `supplyAsync(Supplier\u003CU>)` — запускает асинхронное вычисление, возвращающее результат.\n- `runAsync(Runnable)` — запускает асинхронное вычисление без возврата результата.\n- `completedFuture(U value)` — создаёт уже завершённый `CompletableFuture` с заданным значением.\n\n**2. Трансформация результата (map-подобные):**\n\n- `thenApply(Function\u003CT, U>)` — принимает результат предыдущего этапа, применяет функцию и возвращает новый `CompletableFuture\u003CU>`. Аналог `map` в `Stream`.\n- `thenApplyAsync(Function\u003CT, U>)` — то же, но выполняется в отдельном потоке.\n\n```java\nCompletableFuture\u003CInteger> lengthFuture = CompletableFuture\n    .supplyAsync(() -> \"Привет\")\n    .thenApply(String::length); \u002F\u002F 6\n```\n\n**3. Цепочка асинхронных операций (flatMap-подобные):**\n\n- `thenCompose(Function\u003CT, CompletionStage\u003CU>>)` — принимает результат и возвращает новый `CompletionStage`. Аналог `flatMap`. Используется, когда каждый шаг сам является асинхронным.\n\n```java\nCompletableFuture\u003CString> result = CompletableFuture\n    .supplyAsync(() -> getUserId())\n    .thenCompose(userId -> CompletableFuture.supplyAsync(() -> fetchUser(userId)));\n```\n\n**4. Потребление результата:**\n\n- `thenAccept(Consumer\u003CT>)` — потребляет результат, не возвращая значения.\n- `thenRun(Runnable)` — выполняет действие после завершения, не имея доступа к результату.\n\n**5. Комбинирование двух CompletableFuture:**\n\n- `thenCombine(CompletionStage\u003CU>, BiFunction\u003CT, U, V>)` — ожидает завершения обоих и комбинирует результаты.\n- `thenAcceptBoth(CompletionStage\u003CU>, BiConsumer\u003CT, U>)` — потребляет оба результата.\n- `runAfterBoth(CompletionStage\u003C?>, Runnable)` — выполняет действие после завершения обоих.\n\n```java\nCompletableFuture\u003CDouble> priceFuture = CompletableFuture.supplyAsync(() -> getPrice());\nCompletableFuture\u003CDouble> rateFuture = CompletableFuture.supplyAsync(() -> getExchangeRate());\n\nCompletableFuture\u003CDouble> convertedPrice = priceFuture\n    .thenCombine(rateFuture, (price, rate) -> price * rate);\n```\n\n**6. Выбор первого завершённого:**\n\n- `applyToEither(CompletionStage\u003CT>, Function\u003CT, U>)` — применяет функцию к результату первого завершившегося.\n- `acceptEither(CompletionStage\u003CT>, Consumer\u003CT>)` — потребляет результат первого завершившегося.\n- `runAfterEither(CompletionStage\u003C?>, Runnable)` — выполняет действие после завершения любого из двух.\n\n**7. Обработка ошибок:**\n\n- `exceptionally(Function\u003CThrowable, T>)` — обрабатывает исключение, возвращая значение по умолчанию.\n- `handle(BiFunction\u003CT, Throwable, U>)` — обрабатывает и результат, и исключение. Вызывается всегда.\n- `whenComplete(BiConsumer\u003CT, Throwable>)` — выполняет действие при завершении, не изменяя результат.\n\n```java\nCompletableFuture\u003CString> safe = CompletableFuture\n    .supplyAsync(() -> riskyOperation())\n    .handle((result, ex) -> {\n        if (ex != null) {\n            log.error(\"Ошибка\", ex);\n            return \"fallback\";\n        }\n        return result;\n    });\n```\n\n**8. Множественные CompletableFuture:**\n\n- `allOf(CompletableFuture\u003C?>...)` — возвращает `CompletableFuture\u003CVoid>`, завершающийся, когда все переданные завершены.\n- `anyOf(CompletableFuture\u003C?>...)` — возвращает `CompletableFuture\u003CObject>`, завершающийся при завершении любого.\n\n\u003Cdetails>\n\u003Csummary>Код: сбор результатов через allOf\u003C\u002Fsummary>\n\n```java\nList\u003CCompletableFuture\u003CString>> futures = urls.stream()\n    .map(url -> CompletableFuture.supplyAsync(() -> fetch(url)))\n    .collect(Collectors.toList());\n\nCompletableFuture\u003CVoid> allDone = CompletableFuture.allOf(\n    futures.toArray(new CompletableFuture[0])\n);\n\n\u002F\u002F Собрать все результаты после завершения\nList\u003CString> results = allDone.thenApply(v ->\n    futures.stream()\n        .map(CompletableFuture::join)\n        .collect(Collectors.toList())\n).join();\n```\n\n\u003C\u002Fdetails>\n\n**Ключевые различия:**\n\n| Метод | Аналог в Stream | Назначение |\n|---|---|---|\n| `thenApply` | `map` | Синхронная трансформация |\n| `thenCompose` | `flatMap` | Асинхронная трансформация (разворачивает вложенный CF) |\n| `thenCombine` | — | Объединение двух результатов |\n| `allOf` | — | Ожидание всех |\n| `anyOf` | — | Ожидание любого |\n\n**Каждый метод существует в трёх вариантах:**\n- `thenApply(fn)` — выполняется в потоке, завершившем предыдущий шаг.\n- `thenApplyAsync(fn)` — выполняется в `ForkJoinPool.commonPool()`.\n- `thenApplyAsync(fn, executor)` — выполняется в указанном пуле.\n\n**Частые ошибки:**\n- Путаница между `thenApply` и `thenCompose` — приводит к `CompletableFuture\u003CCompletableFuture\u003CT>>`.\n- `allOf` возвращает `Void` — результаты нужно собирать отдельно из каждого `CompletableFuture`.\n- `exceptionally` после `handle` — `handle` уже обрабатывает исключение, `exceptionally` получит `null`.\n\n> **На собеседовании** ключевой вопрос: «Чем отличается `thenApply` от `thenCompose`?» Запомните: `thenApply` — это `map`, `thenCompose` — это `flatMap`. Если ваша функция сама возвращает `CompletableFuture`, используйте `thenCompose`, иначе получите вложенный future.","","middle",[15,16,17,18,19,20],"allOf","CompletableFuture","exceptionally","thenCompose","thenApply","concurrency",[],null,{"title":24,"description":25,"ogTitle":26,"ogDescription":27,"keywords":28,"schemaAnswer":34,"featuredSnippetReady":35},"Основные методы CompletableFuture в Java — полный обзор — Gymterview","Категории методов CompletableFuture: создание (supplyAsync), трансформация (thenApply), цепочки (thenCompose), комбинирование (thenCombine, allOf), обработка ошибок (exceptionally, handle).","Методы CompletableFuture — создание, трансформация, комбинирование","supplyAsync, thenApply, thenCompose, thenCombine, allOf, anyOf, exceptionally, handle, whenComplete — полный обзор API CompletableFuture.",[29,30,31,32,33],"методы CompletableFuture","thenApply vs thenCompose","exceptionally handle","allOf anyOf","CompletableFuture API","Методы делятся на категории: создание (supplyAsync, runAsync, completedFuture), трансформация (thenApply — аналог map), цепочки (thenCompose — аналог flatMap), потребление (thenAccept, thenRun), комбинирование (thenCombine, thenAcceptBoth), выбор первого (applyToEither, acceptEither), обработка ошибок (exceptionally, handle, whenComplete), множественные (allOf, anyOf). Ключевое различие: thenApply оборачивает результат, thenCompose — разворачивает вложенный CompletableFuture.",true]