Subscribe To Our Newsletter
You will receive our latest post and tutorial.
Thank you for subscribing!

required
required


Functional Interfaces

 

An Interface that contains exactly one abstract method is known as a functional interface. It can have any number of default, static methods but can contain only one abstract method. Functional Interface is also known as Single Abstract Method Interfaces or SAM Interfaces. It is a new feature in Java, which helps to achieve functional programming approach.

 

@FunctionalInterface
public interface AdditionalCalculator {

	int add(int num1, int num2);
}
public class FunctionalInterfaceDemo {

	public static void main(String[] args) {
		AdditionalCalculator add = (int num1, int num2) -> num1+num2;
		
		System.out.println(add.add(2, 4));
	}
}

Result

6

 

 

 

 

 

 

 

 

 

August 5, 2019

Method References

 

 

Method reference is used to refer to a method of a functional interface. It is a compact and easy form of a lambda expression. Each time when you are using a lambda expression to just referring a method, you can replace your lambda expression with method reference.

There are following types of method references in java:

  1. Reference to a static method.
  2. Reference to an instance method.
  3. Reference to a constructor.

Reference to a static method

protected static void methodReferenceWithStaticMethod() {
	List<String> names = Arrays.asList("Laulau","Kinga","Fusi");
		
	names.forEach(MethodReferenceDemo::printMe);
}

public static void printMe(String str) {
	System.out.println("print "+str);
}

 

 

 

Reference to an Object method

List<Integer> numbers = Arrays.asList(5, 3, 50, 24, 40, 2, 9, 18);
numbers = numbers.stream()
		  .sorted((a, b) -> a.compareTo(b)).collect(Collectors.toList());
// equivalent
numbers = numbers.stream().sorted(Integer::compareTo).collect(Collectors.toList());
		
System.out.println(numbers);

Reference with Constructor

class User{
		private String name;
		
		public User(String name) {
			this.name = name;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}
		
		@Override
		public String toString() {
			// TODO Auto-generated method stub
			return this.name;
		}
		
}

....

List<String> names = Arrays.asList("Laulau","Kinga","Fusi");
		
names.forEach(System.out::println);
		
List<User> users = names.stream().map(User::new).collect(Collectors.toList());
	
System.out.println(users);

Result

[Laulau, Kinga, Fusi]

 

August 5, 2019

Lambda Expression

 

A lambda expression is an anonymous method. This anonymous method is not executed on its own. Instead, it is used to implement a method defined by a functional interface. A functional interface is an interface that contains one and only one abstract method which typically represents a single action.

These are characteristics of a lambda expression:

  • Optional type declaration − No need to declare the type of a parameter. The compiler can inference the same from the value of the parameter.
(String a, String b) -> a+" "+b;
// same as
(a, b) -> a+" "+b;
  • Optional parenthesis around parameter − No need to declare a single parameter in parenthesis. For multiple parameters, parentheses are required.
a -> a;
// same as
(a) -> a;
  • Optional curly braces − No need to use curly braces in expression body if the body contains a single statement.
  • Optional return keyword − The compiler automatically returns the value if the body has a single expression to return the value. Curly braces are required to indicate that expression returns a value.
a -> a;
// same as
a -> {return a;};
  • When there are more than one statements, then these must be enclosed in curly brackets (a code block) and the return type of the anonymous function is the same as the type of the value returned within the code block, or void if nothing is returned.
  • A lambda expression can be passed around as if it was an object and executed on demand.
  • Enable to treat functionality as a method argument, or code as data.
public class LambdaTest 
{ 
	interface Operator 
	{ 
		int operation(int a, int b); 
	} 

	public int operate(int a, int b, Operator op) 
	{ 
		return op.operation(a, b); 
	} 

	public static void main(String args[]) 
	{ 
		Operator add = (int x, int y) -> x + y; 

		LambdaTest test = new LambdaTest(); 

		System.out.println("Addition is " + 
						test.operate(6, 3, add)); 

	
	} 
} 

Lambda expressions are used primarily to define inline implementation of a functional interface.

Using lambda expression, you can refer to any final variable or effectively final variable (which is assigned only once). Lambda expression throws a compilation error, if a variable is assigned a value the second time.

@FunctionalInterface annotation

@FunctionalInterface annotation is used to ensure that the functional interface can’t have more than one abstract method. In case more than one abstract methods are present, the compiler flags an ‘Unexpected @FunctionalInterface annotation’ message. However, it is not mandatory to use this annotation.

@FunctionalInterface
public interface Operator {
	int operation(int a, int b);

	// can have static methods
	static String sayHi(String name) {
		return name;
	}
}

Very often, lambda expressions just call methods which are already implemented elsewhere. You can use method references. This is not always shorter, but it makes the code more readable.

a -> a.toLowerCase();
// same as
String::toLowerCase;

Benefits of using Lambda expression

  • Code reuse. The ability to reuse anonymous inner class code is muted, as there’s not way to invoke an it from outside of the code in which it is defined.
  • Readability. No more anonymous inner class. Anonymous inner class can be ugly and not readable.
  • Variables defined outside of an inner class do not employ the traditional rules pertaining to block scope within a Java class.
  • Less boilerplate code. JAR file size reductions.
  •  
Integer[] numbers = {2, 54, 20, 1};
		
Arrays.sort(numbers, new Comparator<Integer>() {
	@Override
	public int compare(Integer a, Integer b) {
		return a - b;
	}
});
		
System.out.println(Arrays.toString(numbers));

How about this version which is much cleaner and more readable.

Integer[] numbers = {2, 54, 20, 1};

Arrays.sort(numbers, (a, b) -> a-b);
		
System.out.println(Arrays.toString(numbers));

 

August 5, 2019

Iterator Pattern

August 4, 2019

State Pattern

August 4, 2019