CompletableFuture made life easy, running things asynchronous

Posted on by

Categories:     

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());
  }
}

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();
    }
  }
}

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

       

Share on:

Author: A N M Bazlur Rahman

Java Champion | Software Engineer | JUG Leader | Book Author | InfoQ & Foojay.IO Editor | Jakarta EE Ambassadors| Helping Java Developers to improve their coding & collaboration skills so that they can meet great people & collaborate

100daysofcode 100daysofjava access advance-java agile algorithm arraylist article bangla-book becoming-expert biginteger book calculator checked checked-exceptions cloning code-readability code-review coding coding-convention collection-framework compact-strings completablefuture concatenation concurrency concurrentmodificationexception concurrentskiplistmap counting countingcollections critical-section daemon-thread data-race data-structure datetime day002 deliberate-practice deserialization design-pattern developers duration execute-around executors export fibonacci file file-copy fork/join-common-pool functional future-java-developers groupby hash-function hashmap history history-of-java how-java-performs-better how-java-works http-client image import inspiration io itext-pdf java java-10 java-11 java-17 java-8 java-9 java-developers java-performance java-programming java-thread java-thread-programming java11 java16 java8 lambda-expression learning learning-and-development linkedlist list local-type-inference localdatetime map methodology microservices nio non-blockingio null-pointer-exception object-cloning optional packaging parallel pass-by-reference pass-by-value pdf performance prime-number programming project-loom race-condition readable-code record refactoring review scheduler scrum serialization serversocket simple-calculator socket software-development softwarearchitecture softwareengineering sorting source-code stack string string-pool stringbuilder swing thread threads tutorial unchecked vector virtual-thread volatile why-java zoneid