DEV Community

loading...

CompletableFuture made life easy, running things asynchronous

A N M Bazlur Rahman
Helping junior software developers to master the top coding and collaboration skills so they get hired to work on amazing projects. #jugbd #MasterDevSkills.com
Originally published at bazlur.com on ・2 min read

100DaysOfProgramming_Day014

Let’s assume you have to invoke two REST APIs and then combine the result. You can run them one by one and then accumulate the result. It looks easy. However, if each call takes up some time, the total time would be pretty significant.

However, we can reduce the time if we can run these two asynchronously, making them parallel. That’s where CompletableFuture comes into play.

Let’s see a code-


package com.bazlur;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Day014 {
  public static void main(String[] args) throws ExecutionException, InterruptedException {
    var stockExchangeService = new StockExchangeService();
    var futureCAD = CompletableFuture.supplyAsync(stockExchangeService::getBitcoinValueInCAD);
    var futureUSD = CompletableFuture.supplyAsync(stockExchangeService::getBitcoinValueInUSD);

    var combined = futureCAD.thenCombine(futureUSD, (cad, usd) -> Stream.of(cad, usd)
            .flatMap(Optional::stream)
            .collect(Collectors.joining(", ")));

    System.out.println("combined = " + combined.get());
  }
}

Enter fullscreen mode Exit fullscreen mode

The stockExchange Service:

package com.bazlur;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;

import java.io.IOException;
import java.util.Optional;

public class StockExchangeService {

  public static final String GOOGLE_FINANCE_QUOTE_BTC_CAD = "https://www.google.com/finance/quote/BTC-CAD";
  public static final String GOOGLE_FINANCE_QUOTE_BTC_USD = "https://www.google.com/finance/quote/BTC-USD";
  public static final String CAD_TEXT = "Bitcoin to Canadian dollar";
  public static final String USD_TEXT = "Bitcoin to United States Dollar";

  public Optional<String> getBitcoinValueInCAD() {
    return getBitConValue(GOOGLE_FINANCE_QUOTE_BTC_CAD, CAD_TEXT);
  }

  public Optional<String> getBitcoinValueInUSD() {
    return getBitConValue(GOOGLE_FINANCE_QUOTE_BTC_USD, USD_TEXT);
  }

  private Optional<String> getBitConValue(String url, String textToFind) {
    var connect = Jsoup.connect(url);
    try {
      var document = connect.get();
      var select = document.select("h2");
      return select.stream()
              .filter(element -> element.text().contains(textToFind))
              .map(Element::parent)
              .map(Element::text)
              .findFirst();
    } catch (IOException e) {
      return Optional.empty();
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

I have used JSoup to parse the text and exact the desired value from it.

for copy/paste pleasure: https://github.com/rokon12/100DaysOfJava/blob/main/src/main/java/com/bazlur/Day014_2.java

Discussion (0)