November 30, 2018

Using lambda and Functional Programming to provide implementation for Callable interface – which prints a string n number of times in java

Callable is a Functional interface, it is similar in usage to Runnable interface. But with a small difference, that Callable can return a value, while Runnable can not return a value.

In this tutorial, we will create a Callable which will return a String output. The string output is going to return String Value, which will be contain a given word  repeated number of times.

Given Values :-

String word = "Refactored ";
int times = 10;

Utility Functions to execute a Callable

private static void executeCallable(Callable<String>  callable) throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        Future<String> callFuture = executorService.submit(callable);
        String repeatedWord = callFuture.get();
        System.out.println(repeatedWord);
        executorService.shutdown();
}

Case 1 :- Using anonymous class to implement Callable interface.

Callable<String> multiply = new Callable<>(){
    StringBuffer sb = new StringBuffer();
    int count = 0 ;

    @Override
    public String call() {
        while(count < times) {
            ++count;
            sb.append(word);
        }
       return sb.toString();
     }

}

Executing this Callable interface.

executeCallable(multiply);

Output :-

Refactored Refactored Refactored Refactored Refactored Refactored Refactored Refactored Refactored Refactored

We can see that, the given word was repeated  number of times.

Case 2 :- Using Lambda to provide implementation for Callable interface.

Callable<String> multiplyLambda = () -> Stream.generate(() -> word)
   .limit(times)
   .reduce(String::concat)
   .get();

The above code, creates a stream of String, which repeatedly returns word.
In next step, We limit the number of elements in the stream.
We pass, a reduce function. Which acts on each of the elements that generated in the stream. And, each element of generated stream is word itself.
The reduce function is String::concat, which concatenates all the elements coming from the stream, i.e it concatenates word with itself, total 10 number of times.
And the last, .get() method returns the final concatenated value. And, the result is the same as that of Anonymous class.

Output From Lambda :-

Refactored Refactored Refactored Refactored Refactored Refactored Refactored Refactored Refactored Refactored

Complete Code :- 

package com.threading;

import java.util.concurrent.*;
import java.util.stream.Stream;

public class LambdaCallable {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        String word = "Refactored ";
        int times = 10;

        Callable<String> multiplyLambda = () -> Stream.generate(() -> word)
                .limit(times)
                .reduce(String::concat).get();

        executeCallable(multiplyLambda);

    }

    private static void executeCallable(Callable<String> callable) throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        Future<String> callFuture = executorService.submit(callable);
        String repeatedWord = callFuture.get();
        System.out.println(repeatedWord);
        executorService.shutdown();
    }
}

 

The above solution is for learning purposes only, it is neither efficient and not memory friendly. 🙂