Java 8+ Functional Programming :: Class Optional<T>

https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html

public final class Optional extends Object

Optional is a container object used to contain not-null objects. Optional object is used to represent null with absent value. This class has various utility methods to facilitate code to handle values as ‘available’ or ‘not available’ instead of checking null values.

Create an empty Optional

An empty Optional object describes the absence of a value. Returns an empty Optional instance. No value is present for this Optional.

API Note:
Though it may be tempting to do so, avoid testing if an object is empty by comparing with == against instances returned by Option.empty(). There is no guarantee that it is a singleton. Instead, use isPresent().
Type Parameters:
T – Type of the non-existent value
Returns:
an empty Optional

	
public static Optional empty() {
    @SuppressWarnings("unchecked")
    Optional t = (Optional) EMPTY;
    return t;
}	

Common instance for empty()

	  
private static final Optional EMPTY = new Optional<>();

Example

	
Optional user = Optional.empty();

 

Create an Optional with a non-null value

If the argument supplied to Optional.of() is null, then it will throw a NullPointerException immediately and the Optional object won’t be created.

Type Parameters:
T – the class of the value
Parameters:
value – the value to be present, which must be non-null
Returns:
an Optional with the value present
Throws:
NullPointerException – if value is null

		
public static  Optional of(T value) {
    return new Optional<>(value);
}	

Example

	
User user = new User("Ian", "Smith");
Optional userOptional = Optional.of(user);

 

Create an Optional with a value which may or may not be null

If the argument passed to Optional.ofNullable() is non-null, then it returns an Optional containing the specified value, otherwise it returns an empty Optional.

Type Parameters:
T – the class of the value
Parameters:
value – the possibly-null value to describe
Returns:
an Optional with a present value if the specified value is non-null, otherwise an empty Optional

	
public static  Optional ofNullable(T value) {
    return value == null ? empty() : of(value);
}

Example

	
Optional userOptional = Optional.ofNullable(user);

 

isPresent()

isPresent() method returns true if the Optional contains a non-null value, otherwise it returns false.

	
public boolean isPresent() {
    return value != null;
}

Example

	
if(optional.isPresent()) {
    // value is present inside Optional
    System.out.println("Value found - " + optional.get());
} else {
    // value is absent
    System.out.println("Optional is empty");
}	

 

ifPresent()

If a value is present, invoke the specified Consumer with the value, otherwise do nothing. The Consumer is executed if a value is present inside the Optional object. It does nothing if the Optional is empty.

Parameters:
consumer – block to be executed if a value is present
Throws:
NullPointerException – if value is present and consumer is null

	
public void ifPresent(Consumer action) {
    if (value != null) {
        action.accept(value);
    }
} 

Example

	
optional.ifPresent(value -> {
    System.out.println("Value found - " + value);
});

 

Retrieving the value using get() method

Optional’s get() method returns a value if it is present, otherwise it throws NoSuchElementException.

Returns:
the non-null value held by this Optional
Throws:
NoSuchElementException – if there is no value present

	
public T get() {
    if (value == null) {
        throw new NoSuchElementException("No value present");
    }
    return value;
}

Example

	
User user = optional.get()

 

Returning default value using orElse()

Return the value if present, otherwise return other (public T orElse(T other)).

Parameters:
other – the value to be returned if there is no value present, may be null
Returns:
the value, if present, otherwise other

	
public T orElse(T other) {
    return value != null ? value : other;
}

Example

	
User user = optionalUser.orElse(new User("", "Unknown User"));

 

Returning default value using orElseGet()

orElseGet() allows you to pass a Supplier function which is invoked when the Optional is empty. Return the value if present, otherwise invoke other and return the result of that invocation.
The result of the Supplier function becomes the default value of the Optional

Parameters:
other – a Supplier whose result is returned if no value is present
Returns:
the value if present otherwise the result of other.get()
Throws:
NullPointerException – if value is not present and other is null

	
public T orElseGet(Supplier supplier) {
    return value != null ? value : supplier.get();
}

Example

	
User user = optionalUser.orElseGet(() -> {
    return new User("", "Unknown User");
});

 

orElseThrow()

Return the contained value, if present, otherwise throw an exception to be created by the provided supplier.

API Note:
A method reference to the exception constructor with an empty argument list can be used as the supplier. For example, IllegalStateException::new
Type Parameters:
X – Type of the exception to be thrown
Parameters:
exceptionSupplier – The supplier which will return the exception to be thrown
Returns:
the present value
Throws:
X – if there is no value present
NullPointerException – if no value is present and exceptionSupplier is null
X extends Throwable

	
public  T orElseThrow(Supplier exceptionSupplier) throws X {
    if (value != null) {
        return value;
    } else {
        throw exceptionSupplier.get();
    }
}

Example

	
public class UserDictionary {

    final HashMap theList = new HashMap<>();
    
    UserDictionary() {
        theList.put(0, "John Doe");
        theList.put(1, "Alfred Neuman");
        theList.put(2, "John Galt");
    }
    
    void addUser(int number, String name) {
        theList.put(number, name);
    }

    Optional getUserByNumber(int number) {
        return Optional.ofNullable(theList.get(number));
    }
}

We can throw an exception if the Optional is empty. orElseThrow() accepts a Supplier that is expected to return an Exception, rather than a constructor, since the Exception can be created lazily. Below we used a lambda that construct a new Exception.

	
public static void main(String[] args) throws Exception {

    UserDictionary userDictionary = new UserDictionary();

    for (int i = 0; i < 4; i++) {         
        String user = userDictionary.getUserByNumber(i)
        .orElseThrow(() -> new Exception("Name not found!"));
        System.err.println("Name " + i + " is " + user);
    }
}

 

Filtering values using filter() method

Optional gives us a way to transform and filter items as they are retrieved. If a value is present, and the value matches the given predicate, return an Optional describing the value, otherwise return an empty Optional.

Parameters:
predicate – a predicate to apply to the value, if present
Returns:
an Optional describing the value of this Optional if a value is present and the value matches the given predicate, otherwise an empty Optional
Throws:
NullPointerException – if the predicate is null

	
public Optional filter(Predicate predicate) {
    Objects.requireNonNull(predicate);
    if (!isPresent()) {
        return this;
    } else {
        return predicate.test(value) ? this : empty();
    }
}

Example

	
userOptional.filter(user -> user.getGender().equalsIgnoreCase("MALE"))
.ifPresent(() -> {
    ...
})

 

Extracting and transforming values using map()

If a value is present, apply the provided mapping function to it, and if the result is non-null, return an Optional describing the result. Otherwise return an empty Optional.

API Note:
This method supports post-processing on optional values, without the need to explicitly check for a return status. For example, the following code traverses a stream of file names, selects one that has not yet been processed, and then opens that file, returning an Optional:

	
         Optional fis =
             names.stream().filter(name -> !isProcessedYet(name))
                           .findFirst()
                           .map(name -> new FileInputStream(name));

Here, findFirst returns an Optional, and then map returns an Optional for the desired file if one exists.
Type Parameters:
U – The type of the result of the mapping function
Parameters:
mapper – a mapping function to apply to the value, if present
Returns:
an Optional describing the result of applying a mapping function to the value of this Optional, if a value is present, otherwise an empty Optional
Throws:
NullPointerException – if the mapping function is null

	
    public  Optional map(Function mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent()) {
            return empty();
        } else {
            return Optional.ofNullable(mapper.apply(value));
        }
    }

Example

	
public static void main(String[] args) {

    UserDictionary userDictionary = new UserDictionary();
    for (int i = 0; i < 3; i++) {         
        userDictionary.getUserByNumber(i)                 
        .map(String::toUpperCase)                 
        .filter(item -> item.charAt(0) != 'J')
        .ifPresent(name -> System.out.println("Name is " + name));
    }
}

 

Cascading Optionals using flatMap()

If a value is present, apply the provided Optional-bearing mapping function to it, return that result, otherwise return an empty Optional. This method is similar to map(Function), but the provided mapper is one whose result is already an Optional, and if invoked, flatMap does not wrap it with an additional Optional.

Type Parameters:
U – The type parameter to the Optional returned by
Parameters:
mapper – a mapping function to apply to the value, if present the mapping function
Returns:
the result of applying an Optional-bearing mapping function to the value of this Optional, if a value is present, otherwise an empty Optional
Throws:
NullPointerException – if the mapping function is null or returns a null result

	
public  Optional flatMap(Function> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent()) {
        return empty();
    } else {
        @SuppressWarnings("unchecked")
        Optional r = (Optional) mapper.apply(value);
        return Objects.requireNonNull(r);
    }
}

Example

	
    public static void main(String[] args) {

        Optional nonEmptyGender = Optional.of("male");
        Optional emptyGender = Optional.empty();

        System.out.println("Non-Empty Optional:: " + nonEmptyGender.map(String::toUpperCase));
        System.out.println("Empty Optional    :: " + emptyGender.map(String::toUpperCase));

        Optional> nonEmptyOtionalGender = Optional.of(Optional.of("male"));
        System.out.println("Optional value   :: " + nonEmptyOtionalGender);
        System.out.println("Optional.map     :: " + nonEmptyOtionalGender.map(gender -> gender.map(String::toUpperCase)));
        System.out.println("Optional.flatMap :: " + nonEmptyOtionalGender.flatMap(gender -> gender.map(String::toUpperCase)));
        
    }

 

Posted in class optional | Tagged | Leave a comment

Java 8+ Functional Programming :: Method References

You use lambda expressions to create anonymous methods. Sometimes, a lambda expression does nothing but call an existing method. In those cases, it’s often clearer to refer to the existing method by name. References are a subset of lambda expressions, because if a lambda expression can be used, then it might be possible to use a method reference, but not always.

There are four kinds of method references:
[table id=6 /]

 

Reference to a Static Method

import java.util.Arrays;
import java.util.List;

public class MethodReference01App {
    public static void main(String args[]) {

        List list = Arrays.asList(1, 2, 3, 4, 5);


        // Method reference
        list.forEach(MethodReference01App::print);
        

        // Lambda expression
        list.forEach(number -> MethodReference01App.print(number));

        // Before Java 8
        for(int number : list) {

        	MethodReference01App.print(number);

        }

    }

    public static void print(final int number) {

        System.out.println("Number: " + number);

    }
}

 

Reference to an Instance Method of a Particular Object

public class MethodReference02App {

	public void saySomething() {
		System.out.println("Reference to an non-static instance method of a particular object.");
	}

	public static void main(String[] args) {

		MethodReference02App methodReference = new MethodReference02App();

		// Referring non-static method using reference
		HelloReference helloReference = methodReference::saySomething;
		// Calling interface method
		helloReference.say();
		
		// Referring non-static method using anonymous object
		HelloReference helloReference2 = new MethodReference02App()::saySomething;
		// Calling interface method
		helloReference2.say();
		
		// Lambda expression
		HelloReference helloReference3 = () -> methodReference.saySomething();
		helloReference3.say();
	}
}

interface HelloReference {
	void say();
}

 

Reference to an Instance Method of an Arbitrary Object of a Particular Type

import java.util.Arrays;
import java.util.List;

public class MethodReference03App {
	
    public static void main(String args[]) {

        final List persons = Arrays.asList(new Person("Tom"), new Person("Harry"));

        // Method reference
        persons.forEach(Person::printName);

        // Lambda expression
        persons.forEach(person -> person.printName());
    }

    private static class Person {
        private String name;

        public Person(final String name) {
            this.name = name;
        }

        public void printName() {
            System.out.println(name);
        }
    }
}

 

Reference to a Constructor

You can refer a constructor by using the new keyword. Here, we are referring constructor with the help of functional interface.

public class MethodReference04App {
	
    public static void main(String[] args) {  
        Sayable hello = Say::new;  
        hello.getMessage("Hello");  
    }  
}

interface Sayable {  
    Say getMessage(String msg);  
}  

class Say {  
    Say(String msg) {  
        System.out.print(msg);  
    }  
} 

 

Posted in functional programming, lambda expression, Method References | Tagged , , | Leave a comment

Java 8+ Functional Programming :: Default Functional Interfaces (some examples)

Functional interfaces provide target types for lambda expressions and method references.

Package – java.util.function.

https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html

The interfaces in this package are general purpose functional interfaces used by the JDK, and are available to be used by user code as well. While they do not identify a complete set of function shapes to which lambda expressions might be adapted, they provide enough to cover common requirements.

Consumer<T>

Consumer can be used in all contexts where an object needs to be consumed, i.e. taken as input, and some operation is to be performed on the object without returning any result. Common example of such an operation is printing where an object is taken as input to the printing function and the value of the object is printed( we will expand upon the printing example in more detail below when understanding how to use Consumer interface).

java.util.function.Consumer source code:

@FunctionalInterface
public interface Consumer {
    void accept(T t);
    default Consumer andThen(Consumer after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

Usage of accept() method of Consumer:

public class Consumer01App {
	
	public static void main(String args[]) {
		
		Consumer consumer = i -> System.out.println(i);
		
		List integerList = Arrays.asList(new Integer(10), new Integer(-5), new Integer(120), new Integer(101));
		printList(integerList, consumer);
	}

	public static void printList(List listOfIntegers, Consumer consumer) {
		for (Integer integer : listOfIntegers) {
			consumer.accept(integer);
		}
	}
}

Usage of default method andThen() of Consumer:

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class Consumer02App {
	
	public static void main(String args[]) {
		
		Consumer consumer = i -> System.out.print(i + "; ");
		Consumer consumerWithAndThen = consumer.andThen( i-> System.out.println("printed " + i));
		
		List integerList = Arrays.asList(new Integer(10), new Integer(-5), new Integer(120), new Integer(101));
		printList(integerList, consumerWithAndThen);
	}

	public static void printList(List listOfIntegers, Consumer consumer) {
		for (Integer integer : listOfIntegers) {
			consumer.accept(integer);
		}
	}
}

 

Function<T,R>

java.util.function.Function source code:

@FunctionalInterface
public interface Function {
    R apply(T t);
    default  Function compose(Function before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }
    default  Function andThen(Function after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }
    static  Function identity() {
        return t -> t;
    }
}

A common usecase is when you want to convert or transform from one object to another. The generic T is the type of the argument and R the type of the object you return.

apply(T t) example:

public class Function01App {
	public static void main(String[] args) {

		Function function = n -> {
			return "Number received: " + n;
		};

		System.out.println(function.apply(17));
	}
}

andThen, compose, indentity example:

	public static void main(String[] args) {
		Function add = n -> (n + 1);
		Function mul = n -> (n * 3);
		Function id = n -> n;
		
		// Using andThen() method
		int a = add.andThen(mul).apply(50);
		System.out.println(a);
		
		// Using compose function
		int c = add.compose(mul).apply(50);
		System.out.println(c);
		
		// Using identity
		System.out.println(id.apply(31));
	}

 

Predicate<T>

java.util.function.Predicate source code:

@FunctionalInterface
public interface Predicate {

    // Evaluates this predicate on the given argument.
    boolean test(T t);

	// Returns a composed predicate that represents a short-circuiting logical AND of this predicate and another.
    default Predicate and(Predicate other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

	// Returns a predicate that represents the logical negation of this predicate.
    default Predicate negate() {
        return (t) -> !test(t);
    }

	// Returns a composed predicate that represents a short-circuiting logical OR of this predicate and another.
    default Predicate or(Predicate other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

	// Returns a predicate that tests if two arguments are equal according to Objects.equals(Object, Object).
    static  Predicate isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}

Example

Usage of the test() method.

public class Predicate01App {
	public static void main(String[] args) {

		Predicate predicateString = s -> {
			return s.equals("Hello");
		};

		// String
		System.out.println(predicateString.test("Hello"));
		System.out.println(predicateString.test("Hello World"));

		// Integer
		Predicate predicateInt = i -> {
			return i > 0;
		};

		System.out.println(predicateInt.test(1));
		System.out.println(predicateInt.test(-1));
	}
}

Example

Usage of the default methods and(), or() and negate().

public class Predicate02App {
	
	public static void main(String[] args) {
		
		Predicate predicate = s -> {
			return s.equals("Hello");
		};
		
		// and logical operation  
		Predicate predicateAnd = predicate.and(s -> s.length() > 4);
		System.out.println(predicateAnd.test("Hello"));
		
		// or logical operation
		Predicate predicateOr = predicate.or(s -> s.length() == 10);
		System.out.println(predicateOr.test("Hello"));
		
		// negate logical operation
		Predicate predicateNegate = predicate.negate();
		System.out.println(predicateNegate.test("Hello"));
	}
}

 

Posted in default method, functional interface, functional programming, lambda, lambda expression | Tagged , , , , | Leave a comment

Java 8+ Functional Programming :: Default Methods

Default methods enable developers to add new functionalities to interfaces without breaking the existing implementation of these interfaces. Default methods are implicitly public. It provides flexibility to allow interface define implementation which will use as default in the situation where a concrete class fails to provide an implementation for that method.

public class DefaultMehod01App implements InterfaceA {

	public static void main(String[] args) {
		DefaultMehod01App say = new DefaultMehod01App();
		say.sayHello();
	}

}

interface InterfaceA {
	default void sayHello() {
		System.out.println("Hello ...");
	}
}

InterfaceA defines a method sayHallo() and provide a default implementation as well. If any class implements this interface then it don’t need to implement it’s own version of ayHallo() method. It can directly call instance of sayHello(). The implementation will be used as default if a concrete class does not provide implementation for that method.

 

Why default methods are needed in java 8?

– to enable the functionality of lambda expression in java.
To support lambda expressions, all core classes have to be modified. Modify one interface in JDK framework breaks all classes that extends the interface. It means that adding any new method could break a lot of lines of code.

Example

The Iterable interface.

public interface Iterable {

public default void forEach(Consumer consumer) {

    for (T t : this) {

        consumer.accept(t);

    }
}
}

The default method can be provided to an interface without affecting implementing classes as it includes an implementation.

 

Static methods

The interfaces can have static methods which is similar to static method of classes.

public static void main(String args[]) {
		DefaultMethod02App d = new DefaultMethod02App();
		d.square(12);

		// Static method executed
		FuntionalInterface.show();
	}

	// Implementation of abstract method
	public void square(int a) {
		System.out.println(a * a);
	}
}

interface FuntionalInterface {
	// abstract method
	public void square(int a);

	// static method
	static void show() {
		System.out.println("Static Method");
	}
}

 

Conflicts with Multiple Interface

Example

public interface InterfaceA { 

    default void defaultMethod(){ 

        System.out.println("Interface A default method"); 

    } 

}

public interface InterfaceB {

    default void defaultMethod(){

        System.out.println("Interface B default method");

    }

}

public class Impl implements InterfaceA, InterfaceB  {

}

Since classes in Java can implement multiple interfaces, there could be a situation where two or more interfaces has a default method with the same signature causing conflicts as java will not know what methods to use at a time. Additionally, a interface can also extend another interface as well.

Rules for this conflict resolution:

  • Rule 1 – Most preferred are the overridden methods in classes. Classes take higher precedence than interfaces – Any method inherited from a class or a superclass is invoked over any default method inherited from an interface.
  • Rule 2 – Derived interfaces or sub-interfaces take higher precedence than the interfaces higher-up in the inheritance hierarchy – If default methods with the same method signature exist in an interface and its child interfaces, then the default method from the child interface is invoked.
  • Rule 3 – In case Rule 1 and Rule 2 are not able to resolve the conflict then the implementing class has to specifically override and provide a method with the same method definition.

 

Posted in default method, functional interface, functional programming, lambda, lambda expression | Tagged , , , , | Leave a comment

Java 8+ Functional Programming :: Functional Interfaces and Lambda Expressions

A functional interface is an interface that contains only one abstract method.
Lambda expression can be used to represent the instance of a functional interface.
Any interface with a single abstract method is a functional interface, and its implementation may be treated as lambda expressions.
A functional interface can have any number of default methods.

 

Example

@FunctionalInterface
interface Square {
    int calculate(int x);
}

@FunctionalInterface annotation is used to ensure that the functional interface can’t have more than one abstract method.
It is not mandatory to use this annotation.

Example

Lamda expression – implementation of the functional interface Square:

Square square = (int x) -> x*x;

where:
square – implementation;
(int x) -> x*x means int f(int x) { return x*x; }
In this notation the lambda expression is an anonymous method.

Usage of the lambada expression:
int s = square.calculate(2);
System.out.println(s);

Example

@FunctionalInterface
interface Square {
    int calculate(int x);
}
 
class Test {
    public static void main(String args[]) {
 
        // lambda expression that define the calculated method: int calculate(int x)
        Square square = (int x) -> x*x;
 
		// usage
		int a = 2;
        int s = square.calculate(a);
        System.out.println(s);
    }
}

Example

public class Lambda01App {

	public static void main(String args[]) {
		Lambda01App tester = new Lambda01App();

		MathOperation addition = (int a, int b) -> a + b;

		MathOperation subtraction = (int a, int b) -> a - b;

		MathOperation multiplication = (int a, int b) -> {
			return a * b;
		};

		MathOperation division = (a, b) -> a / b;

		System.out.println("3 + 2 = " + tester.operate(3, 2, addition));
		System.out.println("7 - 5 = " + tester.operate(7, 5, subtraction));
		System.out.println("3 * 5 = " + tester.operate(3, 5, multiplication));
		System.out.println("15 / 5 = " + tester.operate(15, 5, division));
		
		// or otherwise:
		
		System.out.println("3 + 2 = " + tester.operate(3, 2, (int a, int b) -> a + b));
		System.out.println("7 - 5 = " + tester.operate(7, 5, (int a, int b) -> a - b));
		System.out.println("3 * 5 = " + tester.operate(3, 5, (int a, int b) -> { return a * b; }));
		System.out.println("15 / 5 = " + tester.operate(15, 5, (a, b) -> a / b));			
	}
	
	interface MathOperation {
		int operation(int a, int b);
	}

	private int operate(int a, int b, MathOperation mathOperation) {
		return mathOperation.operation(a, b);
	}
}

Also possible:

MathOperation addition = (a, b) -> a + b;
MathOperation multiplication = (a, b) -> {
return a + b;
};

because the interface MathOperation recognizes types.

Example

public class Lambda02App {
	
	public static void main(String args[]) {
		
		List list = Arrays.asList("Adam Moore", "Jack Huber", "Karl Garcia", "Harry Marino", "Karl Jansen", "Lukas Wagner", "Peter Nowak", "Robert Olsen", "Kim Mazur");

		// Predicate predicate = s -> true
		// s is passed as parameter to test method of Predicate interface.
		// test method will always return true no matter what value n has.
		System.out.println("Print all names:");

		
		// pass s as parameter
		eval(list, n -> true);

		
		// Predicate predicate1 = s -> s.contains("Karl")
		// s is passed as parameter to test method of Predicate interface.
		// test method will return true if s.contains("Karl")
		System.out.println("\n\nPrint names containing 'Karl':");
		eval(list, s -> s.contains("Karl"));
		

		// Predicate predicate2 = s -> (s.compareTo("Harry Mario") > 1)
		// s is passed as parameter to test method of Predicate interface.
		// test method will return true if s.compareTo("Harry Mario") > 1.
		System.out.println("\n\nPrint names greater than 'Harry Mario':");
		eval(list, s -> (s.compareTo("Harry Mario") > 1));
		
	}

	public static void eval(List list, Predicate predicate) {

		for (String s : list) {
			if (predicate.test(s)) {
				System.out.println(s);
			}
		}
	}
	
	@FunctionalInterface
	public interface Predicate {
	    boolean test(T t);
	}    
}

 

Posted in functional interface, functional programming, lambda, lambda expression | Tagged , , , | Leave a comment