Functional Programming – Terminal Methods ”; Previous Next When a terminal method in invoked on a stream, iteration starts on stream and any other chained stream. Once the iteration is over then the result of terminal method is returned. A terminal method does not return a Stream thus once a terminal method is invoked over a stream then its chaining of non-terminal methods or intermediate methods stops/terminates. Generally, terminal methods returns a single value and are invoked on each element of the stream. Following are some of the important terminal methods of Stream interface. Each terminal function takes a predicate function, initiates the iterations of elements, apply the predicate on each element. anyMatch − If predicate returns true for any of the element, it returns true. If no element matches, false is returned. allMatch − If predicate returns false for any of the element, it returns false. If all element matches, true is returned. noneMatch − If no element matches, true is returned otherwise false is returned. collect − each element is stored into the collection passed. count − returns count of elements passed through intermediate methods. findAny − returns Optional instance containing any element or empty instance is returned. findFirst − returns first element under Optional instance. For empty stream, empty instance is returned. forEach − apply the consumer function on each element. Used to print all elements of a stream. min − returns the smallest element of the stream. Compares elements based on comparator predicate passed. max − returns the largest element of the stream. Compares elements based on comparator predicate passed. reduce − reduces all elements to a single element using the predicate passed. toArray − returns arrays of elements of stream. Example – Terminal Methods import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class FunctionTester { public static void main(String[] args) { List<String> stringList = Arrays.asList(“One”, “Two”, “Three”, “Four”, “Five”, “One”); System.out.println(“Example – anyMatchn”); //anyMatch – check if Two is present? System.out.println(“Two is present: ” + stringList .stream() .anyMatch(s -> {return s.contains(“Two”);})); System.out.println(“nExample – allMatchn”); //allMatch – check if length of each string is greater than 2. System.out.println(“Length > 2: ” + stringList .stream() .allMatch(s -> {return s.length() > 2;})); System.out.println(“nExample – noneMatchn”); //noneMatch – check if length of each string is greater than 6. System.out.println(“Length > 6: ” + stringList .stream() .noneMatch(s -> {return s.length() > 6;})); System.out.println(“nExample – collectn”); System.out.println(“List: ” + stringList .stream() .filter(s -> {return s.length() > 3;}) .collect(Collectors.toList())); System.out.println(“nExample – countn”); System.out.println(“Count: ” + stringList .stream() .filter(s -> {return s.length() > 3;}) .count()); System.out.println(“nExample – findAnyn”); System.out.println(“findAny: ” + stringList .stream() .findAny().get()); System.out.println(“nExample – findFirstn”); System.out.println(“findFirst: ” + stringList .stream() .findFirst().get()); System.out.println(“nExample – forEachn”); stringList .stream() .forEach(System.out::println); System.out.println(“nExample – minn”); System.out.println(“min: ” + stringList .stream() .min((s1, s2) -> { return s1.compareTo(s2);})); System.out.println(“nExample – maxn”); System.out.println(“min: ” + stringList .stream() .max((s1, s2) -> { return s1.compareTo(s2);})); System.out.println(“nExample – reducen”); System.out.println(“reduced: ” + stringList .stream() .reduce((s1, s2) -> { return s1 + “, “+ s2;}) .get()); } } Output Example – anyMatch Two is present: true Example – allMatch Length > 2: true Example – noneMatch Length > 6: true Example – collect List: [Three, Four, Five] Example – count Count: 3 Example – findAny findAny: One Example – findFirst findFirst: One Example – forEach One Two Three Four Five One Example – min min: Optional[Five] Example – max min: Optional[Two] Example – reduce reduced: One, Two, Three, Four, Five, One Print Page Previous Next Advertisements ”;
Category: functional Programming With Java
First Class Functions
Functional Programming – First Class Function ”; Previous Next A function is called a first class function if it fulfills the following requirements. It can be passed as a parameter to a function. It can be returned from a function. It can be assigned to a variable and then can be used later. Java 8 supports functions as first class object using lambda expressions. A lambda expression is a function definition and can be assigned to a variable, can be passed as an argument and can be returned. See the example below − @FunctionalInterface interface Calculator<X, Y> { public X compute(X a, Y b); } public class FunctionTester { public static void main(String[] args) { //Assign a function to a variable Calculator<Integer, Integer> calculator = (a,b) -> a * b; //call a function using function variable System.out.println(calculator.compute(2, 3)); //Pass the function as a parameter printResult(calculator, 2, 3); //Get the function as a return result Calculator<Integer, Integer> calculator1 = getCalculator(); System.out.println(calculator1.compute(2, 3)); } //Function as a parameter static void printResult(Calculator<Integer, Integer> calculator, Integer a, Integer b){ System.out.println(calculator.compute(a, b)); } //Function as return value static Calculator<Integer, Integer> getCalculator(){ Calculator<Integer, Integer> calculator = (a,b) -> a * b; return calculator; } } Output 6 6 6 Print Page Previous Next Advertisements ”;
Parallelism
Functional Programming with Java – Parallelism ”; Previous Next Parallelism is a key concept of functional programming where a big task is accomplished by breaking in smaller independent tasks and then these small tasks are completed in a parallel fashion and later combined to give the complete result. With the advent of multi-core processors, this technique helps in faster code execution. Java has Thread based programming support for parallel processing but it is quite tedious to learn and difficult to implement without bugs. Java 8 onwards, stream have parallel method and collections has parallelStream() method to complete tasks in parallel fashion. See the example below: import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class FunctionTester { public static void main(String[] args) { Integer[] intArray = {1, 2, 3, 4, 5, 6, 7, 8 }; List<Integer> listOfIntegers = new ArrayList<>(Arrays.asList(intArray)); System.out.println(“List using Serial Stream:”); listOfIntegers .stream() .forEach(e -> System.out.print(e + ” “)); System.out.println(“”); System.out.println(“List using Parallel Stream:”); listOfIntegers .parallelStream() .forEach(e -> System.out.print(e + ” “)); System.out.println(“”); System.out.println(“List using Another Parallel Stream:”); listOfIntegers .stream() .parallel() .forEach(e -> System.out.print(e + ” “)); System.out.println(“”); System.out.println(“List using Parallel Stream but Ordered:”); listOfIntegers .parallelStream() .forEachOrdered(e -> System.out.print(e + ” “)); System.out.println(“”); } } Output List using Serial Stream: 1 2 3 4 5 6 7 8 List using Parallel Stream: 6 5 8 7 3 4 2 1 List using Another Parallel Stream: 6 2 1 7 4 3 8 5 List using Parallel Stream but Ordered: 1 2 3 4 5 6 7 8 Print Page Previous Next Advertisements ”;
Optionals & Monads
Optionals and Monads ”; Previous Next Monad is a key concept of Functional Programming. A Monad is a design pattern which helps to represent a missing value. It allows to wrap a potential null value, allows to put transformation around it and pull actual value if present. By definition, a monad is a set of following parameters. A parametrized Type − M<T> A unit Function − T −> M<T> A bind operation − M<T> bind T −> M<U> = M<U> Key Operations Left Identity − If a function is bind on a monad of a particular value then its result will be same as if function is applied to the value. Right Identity − If a monad return method is same as monad on original value. Associativity − Functions can be applied in any order on a monad. Optional Class Java 8 introduced Optional class which is a monad. It provides operational equivalent to a monad. For example return is a operation which takes a value and return the monad. Optional.of() takes a parameters and returns the Optional Object. On similar basis , bind is operation which binds a function to a monad to produce a monad. Optional.flatMap() is the method which performs an operation on Optional and return the result as Optional. A parametrized Type − Optional<T> A unit Function − Optional.of() A bind operation − Optional.flatMap() Example − Left Identity Following example shows how Optional class obeys Left Identity rule. import java.util.Optional; import java.util.function.Function; public class FunctionTester { public static void main(String[] args) { Function<Integer, Optional<Integer>> addOneToX = x −> Optional.of(x + 1); System.out.println(Optional.of(5).flatMap(addOneToX) .equals(addOneToX.apply(5))); } } Output true Example − Right Identity Following example shows how Optional class obeys Right Identity rule. import java.util.Optional; public class FunctionTester { public static void main(String[] args) { System.out.println(Optional.of(5).flatMap(Optional::of) .equals(Optional.of(5))); } } Output true Example – Associativity Following example shows how Optional class obeys Associativity rule. import java.util.Optional; import java.util.function.Function; public class FunctionTester { public static void main(String[] args) { Function<Integer, Optional<Integer>> addOneToX = x −> Optional.of(x + 1); Function<Integer, Optional<Integer>> addTwoToX = x −> Optional.of(x + 2); Function<Integer, Optional<Integer>> addThreeToX = x −> addOneToX.apply(x).flatMap(addTwoToX); Optional.of(5).flatMap(addOneToX).flatMap(addTwoToX) .equals(Optional.of(5).flatMap(addThreeToX)); } } Output true Print Page Previous Next Advertisements ”;
Default Methods
Functional Programming – Default Methods ”; Previous Next Java 8 introduces a new concept of default method implementation in interfaces. This capability is added for backward compatibility so that old interfaces can be used to leverage the lambda expression capability of Java 8. For example, ”List” or ”Collection” interfaces do not have ”forEach” method declaration. Thus, adding such method will simply break the collection framework implementations. Java 8 introduces default method so that List/Collection interface can have a default implementation of forEach method, and the class implementing these interfaces need not implement the same. Syntax public interface vehicle { default void print() { System.out.println(“I am a vehicle!”); } } Multiple Defaults With default functions in interfaces, there is a possibility that a class is implementing two interfaces with same default methods. The following code explains how this ambiguity can be resolved. public interface vehicle { default void print() { System.out.println(“I am a vehicle!”); } } public interface fourWheeler { default void print() { System.out.println(“I am a four wheeler!”); } } First solution is to create an own method that overrides the default implementation. public class car implements vehicle, fourWheeler { public void print() { System.out.println(“I am a four wheeler car vehicle!”); } } Second solution is to call the default method of the specified interface using super. public class car implements vehicle, fourWheeler { default void print() { vehicle.super.print(); } } Static Default Methods An interface can also have static helper methods from Java 8 onwards. public interface vehicle { default void print() { System.out.println(“I am a vehicle!”); } static void blowHorn() { System.out.println(“Blowing horn!!!”); } } Default Method Example Create the following Java program using any editor of your choice in, say, C:> JAVA. Java8Tester.java public class Java8Tester { public static void main(String args[]) { Vehicle vehicle = new Car(); vehicle.print(); } } interface Vehicle { default void print() { System.out.println(“I am a vehicle!”); } static void blowHorn() { System.out.println(“Blowing horn!!!”); } } interface FourWheeler { default void print() { System.out.println(“I am a four wheeler!”); } } class Car implements Vehicle, FourWheeler { public void print() { Vehicle.super.print(); FourWheeler.super.print(); Vehicle.blowHorn(); System.out.println(“I am a car!”); } } Verify the Result Compile the class using javac compiler as follows − C:JAVA>javac Java8Tester.java Now run the Java8Tester as follows − C:JAVA>java Java8Tester It should produce the following output − I am a vehicle! I am a four wheeler! Blowing horn!!! I am a car! Print Page Previous Next Advertisements ”;
Persistent Data Structure
Persistent Data Structure ”; Previous Next A data structure is said to be persistent if it is capable to maintaining its previous updates as separate versions and each version can be accessed and updated accordingly. It makes the data structure immutable and thread safe. For example, String class object in Java is immutable. Whenever we make any change to string, JVM creates another string object, assigned it the new value and preserve the older value as old string object. A persistent data structure is also called a functional data structure. Consider the following case − Non-Persistent way public static Person updateAge(Person person, int age){ person.setAge(age); return person; } Persistent way public static Person updateAge(Person pPerson, int age){ Person person = new Person(); person.setAge(age); return person; } Print Page Previous Next Advertisements ”;
Infinite Streams
Functional Programming – Infinite Streams ”; Previous Next Collections are in-memory data structure which have all the elements present in the collection and we have external iteration to iterate through collection whereas Stream is a fixed data structure where elements are computed on demand and a Stream has inbuilt iteration to iterate through each element. Following example shows how to create a Stream from an array. int[] numbers = {1, 2, 3, 4}; IntStream numbersFromArray = Arrays.stream(numbers); Above stream is of fixed size being built from an array of four numbers and will not return element after 4th element. But we can create a Stream using Stream.iterate() or Stream.generate() method which can have lamdba expression will pass to a Stream. Using lamdba expression, we can pass a condition which once fulfilled give the required elements. Consider the case, where we need a list of numbers which are multiple of 3. Example – Infinite Stream import java.util.stream.Stream; public class FunctionTester { public static void main(String[] args) { //create a stream of numbers which are multiple of 3 Stream<Integer> numbers = Stream.iterate(0, n -> n + 3); numbers .limit(10) .forEach(System.out::println); } } Output 0 3 6 9 12 15 18 21 24 27 In order to operate on infinite stream, we”ve used limit() method of Stream interface to restrict the iteration of numbers when their count become 10. Print Page Previous Next Advertisements ”;
Quick Guide
Functional Programming with Java – Quick Guide ”; Previous Next Functional Programming – Overview In functional programming paradigm, an application is written mostly using pure functions. Here pure function is a function having no side effects. An example of side effect is modification of instance level variable while returning a value from the function. Following are the key aspects of functional programming. Functions − A function is a block of statements that performs a specific task. Functions accept data, process it, and return a result. Functions are written primarily to support the concept of re usability. Once a function is written, it can be called easily, without having to write the same code again and again. Functional Programming revolves around first class functions, pure functions and high order functions. A First Class Function is the one that uses first class entities like String, numbers which can be passed as arguments, can be returned or assigned to a variable. A High Order Function is the one which can either take a function as an argument and/or can return a function. A Pure Function is the one which has no side effect while its execution. Functional Composition − In imperative programming, functions are used to organize an executable code and emphasis is on organization of code. But in functional programming, emphasis is on how functions are organized and combined. Often data and functions are passed together as arguments and returned. This makes programming more capable and expressive. Fluent Interfaces − Fluent interfaces helps in composing expressions which are easy to write and understand. These interfaces helps in chaining the method call when each method return type is again reused. For example − LocalDate futureDate = LocalDate.now().plusYears(2).plusDays(3); Eager vs Lazy Evaluation − Eager evaluation means expressions are evaluated as soon as they are encountered whereas lazy evaluation refers to delaying the execution till certain condition is met. For example, stream methods in Java 8 are evaluated when a terminal method is encountered. Persistent Data Structures − A persistent data structure maintains its previous version. Whenever data structure state is changed, a new copy of structure is created so data structure remains effectively immutable. Such immutable collections are thread safe. Recursion − A repeated calculation can be done by making a loop or using recursion more elegantly. A function is called recursive function if it calls itself. Parallelism − Functions with no side effects can be called in any order and thus are candidate of lazy evaluation. Functional programming in Java supports parallelism using streams where parallel processing is provided. Optionals − Optional is a special class which enforces that a function should never return null. It should return value using Optional class object. This returned object has method isPresent which can be checked to get the value only if present. Functional Programming with Java – Functions A function is a block of statements that performs a specific task. Functions accept data, process it, and return a result. Functions are written primarily to support the concept of re usability. Once a function is written, it can be called easily, without having to write the same code again and again. Functional Programming revolves around first class functions, pure functions and high order functions. A First Class Function is the one that uses first class entities like String, numbers which can be passed as arguments, can be returned or assigned to a variable. A High Order Function is the one which can take a function as an argument and/or can return a function. A Pure Function is the one which has no side effect while its execution. First Class Function A first class function can be treated as a variable. That means it can be passed as a parameter to a function, it can be returned by a function or can be assigned to a variable as well. Java supports first class function using lambda expression. A lambda expression is analogous to an anonymous function. See the example below − public class FunctionTester { public static void main(String[] args) { int[] array = {1, 2, 3, 4, 5}; SquareMaker squareMaker = item -> item * item; for(int i = 0; i < array.length; i++){ System.out.println(squareMaker.square(array[i])); } } } interface SquareMaker { int square(int item); } Output 1 4 9 16 25 Here we have created the implementation of square function using a lambda expression and assigned it to variable squareMaker. High Order Function A high order function either takes a function as a parameter or returns a function. In Java, we can pass or return a lambda expression to achieve such functionality. import java.util.function.Function; public class FunctionTester { public static void main(String[] args) { int[] array = {1, 2, 3, 4, 5}; Function<Integer, Integer> square = t -> t * t; Function<Integer, Integer> cube = t -> t * t * t; for(int i = 0; i < array.length; i++){ print(square, array[i]); } for(int i = 0; i < array.length; i++){ print(cube, array[i]); } } private static <T, R> void print(Function<T, R> function, T t ) { System.out.println(function.apply(t)); } } Output 1 4 9 16 25 1 8 27 64 125 Pure Function A pure function does not modify any global variable or modify any reference passed as a parameter to it. So it has no side-effect. It always returns the same value when invoked with same parameters. Such functions are very useful and are thread safe. In example below, sum is a pure function. public class FunctionTester { public static void main(String[] args) { int a, b; a = 1; b = 2; System.out.println(sum(a, b)); } private static int sum(int a, int b){ return a + b; } } Output 3 Functional Programming with Java – Composition Functional composition refers to a technique where multiple functions are combined together to a single function. We can combine lambda expression together. Java provides inbuilt support using Predicate and Function classes. Following example shows how to combine two functions using predicate approach. import java.util.function.Predicate;
Eager vs Lazy Evaluation
Eager vs Lazy Evaluation ”; Previous Next Eager evaluation means expression is evaluated as soon as it is encountered where as lazy evaluation refers to evaluation of an expression when needed. See the following example to under the concept. import java.util.function.Supplier; public class FunctionTester { public static void main(String[] args) { String queryString = “password=test”; System.out.println(checkInEagerWay(hasName(queryString) , hasPassword(queryString))); System.out.println(checkInLazyWay(() -> hasName(queryString) , () -> hasPassword(queryString))); } private static boolean hasName(String queryString){ System.out.println(“Checking name: “); return queryString.contains(“name”); } private static boolean hasPassword(String queryString){ System.out.println(“Checking password: “); return queryString.contains(“password”); } private static String checkInEagerWay(boolean result1, boolean result2){ return (result1 && result2) ? “all conditions passed”: “failed.”; } private static String checkInLazyWay(Supplier<Boolean> result1, Supplier<Boolean> result2){ return (result1.get() && result2.get()) ? “all conditions passed”: “failed.”; } } Output Checking name: Checking password: failed. Checking name: failed. Here checkInEagerWay() function first evaluated the parameters then executes its statement. Whereas checkInLazyWay() executes its statement and evaluates the parameter on need basis. As && is a short-circuit operator, checkInLazyWay only evaluated first parameter which comes as false and does not evaluate the second parameter at all. Print Page Previous Next Advertisements ”;
Closure
Functional Programming with Java – Closure ”; Previous Next A closure is a function which is a combination of function along with its surrounding state. A closure function generally have access to outer function”s scope. In the example given below, we have created a function getWeekDay(String[] days) which returns a function which can return the text equivalent of a weekday. Here getWeekDay() is a closure which is returning a function surrounding the calling function”s scope. Following example shows how Closure works. import java.util.function.Function; public class FunctionTester { public static void main(String[] args) { String[] weekDays = {“Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”, “Sunday” }; Function<Integer, String> getIndianWeekDay = getWeekDay(weekDays); System.out.println(getIndianWeekDay.apply(6)); } public static Function<Integer, String> getWeekDay(String[] weekDays){ return index -> index >= 0 ? weekDays[index % 7] : null; } } Output Sunday Print Page Previous Next Advertisements ”;