Java 8 Functional Interfaces

Welcome to the Java 8 useful interfaces precedent instructional exercise. Java has dependably been an Object Oriented Programming language. What is implies that everything in java programming rotates around Objects (aside from some crude kinds for effortlessness). We don't have just capacities in java, they are a piece of Class and we have to utilize the class/item to conjure any function.

Java 8 Functional Interfaces

On the off chance that we investigate some other programming dialects, for example, C++, JavaScript; they are called functional programming language in light of the fact that we can compose capacities and utilize them when required. A portion of these dialects bolster Object Oriented Programming just as Functional Programming.

Being object arranged isn't terrible, yet it conveys a ton of verbosity to the program. For instance, suppose we need to make a case of Runnable. Typically we do it utilizing mysterious classes like below.


Runnable r = new Runnable(){ 


public void run() { 

System.out.println("My Runnable"); 


If you take a gander at the above code, the real part that is useful is the code inside run() strategy. Rest the majority of the code is a result of the manner in which java programs are structured.

Java 8 Functional Interfaces and Lambda Expressions help us recorded as a hard copy littler and cleaner code by evacuating a ton of standard code.

Java 8 Functional Interface

An interface with precisely one dynamic strategy is called Functional Interface. @FunctionalInterface comment is included so we can check an interface as practical interface.

It isn't required to utilize it, however it's best practice to utilize it with useful interfaces to maintain a strategic distance from expansion of additional techniques incidentally. On the off chance that the interface is commented on with @FunctionalInterface comment and we attempt to have more than one conceptual technique, it tosses compiler error.

The real advantage of java 8 utilitarian interfaces is that we can utilize lambda expressions to instantiate them and abstain from utilizing cumbersome unknown class implementation.

Java 8 Collections API has been reworked and new Stream API is presented that utilizes a great deal of useful interfaces. Java 8 has characterized a great deal of practical interfaces in java.util.function bundle. A portion of the helpful java 8 useful interfaces are Consumer, Supplier, Function and Predicate.

java.lang.Runnable is an extraordinary case of utilitarian interface with single dynamic technique run().

Below code bit gives some direction to utilitarian interfaces:

interface Foo { boolean equals(Object obj); } // Not functional because equals is already an implicit member (Object class) interface Comparator<T> { boolean equals(Object obj); int compare(T o1, T o2); } // Functional because Comparator has only one abstract non-Object method interface Foo { int m(); Object clone(); } // Not functional because method Object.clone is not public interface X { int m(Iterable<String> arg); } interface Y { int m(Iterable<String> arg); } interface Z extends X, Y {} // Functional: two methods, but they have the same signature interface X { Iterable m(Iterable<String> arg); } interface Y { Iterable<String> m(Iterable arg); } interface Z extends X, Y {} // Functional: Y.m is a subsignature & return-type-substitutable interface X { int m(Iterable<String> arg); } interface Y { int m(Iterable<Integer> arg); } interface Z extends X, Y {} // Not functional: No method has a subsignature of all abstract methods interface X { int m(Iterable<String> arg, Class c); } interface Y { int m(Iterable arg, Class<?> c); } interface Z extends X, Y {} // Not functional: No method has a subsignature of all abstract methods interface X { long m(); } interface Y { int m(); } interface Z extends X, Y {} // Compiler error: no method is return type substitutable interface Foo<T> { void m(T arg); } interface Bar<T> { void m(T arg); } interface FooBar<X, Y> extends Foo<X>, Bar<Y> {} // Compiler error: different signatures, same erasure

Lambda Expression

Lambda Expression are the path through which we can envision functional programming in the java object arranged world. Articles are the base of java programming language and we can never have a capacity without an Object, that is the reason Java language offer help for utilizing lambda articulations just with useful interfaces.

Since there is just a single conceptual capacity in the practical interfaces, there is no perplexity in applying the lambda articulation to the technique. Lambda Expressions sentence structure is (argument) - > (body). Presently how about we perceive how we can compose above mysterious Runnable utilizing lambda expression.


Runnable r1 = () - > System.out.println("My Runnable"); 

Let's attempt to comprehend what's going on in the lambda articulation above.

  • Runnable is a useful interface, that is the reason we can utilize lambda articulation to make it's instance.
  • Since run() technique takes no contention, our lambda articulation likewise have no argument.
  • Just like if-else squares, we can maintain a strategic distance from wavy props ({}) since we have a solitary articulation in the technique body. For numerous announcements, we would need to utilize wavy supports like some other methods.

Why do we need Lambda Expression

  1. Reduced Lines of Code
    One of the reasonable advantage of utilizing lambda articulation is that the measure of code is decreased, we have just observed that how effectively we can make case of an utilitarian interface utilizing lambda articulation instead of utilizing mysterious class.
  2. Sequential and Parallel Execution Support

    Another advantage of utilizing lambda articulation is that we can profit by the Stream API consecutive and parallel tasks support.

    To clarify this present, how about we take a basic precedent where we have to compose a technique to test if a number passed is prime number or not.

    Traditionally we would compose it's code like underneath. The code isn't completely streamlined yet useful for instance reason, so hold on for me on this.

    //Traditional approach private static boolean isPrime(int number) { if(number < 2) return false; for(int i=2; i<number; i++){ if(number % I == 0) return false; } return true; }

    The issue with above code is that it's successive in nature, on the off chance that the number is colossal, at that point it will require noteworthy measure of investment. Another issue with code is that there are such a large number of leave focuses and it's not discernible. We should perceive how we can compose a similar technique utilizing lambda articulations and stream API.

    //Declarative approach private static boolean isPrime(int number) { return number > 1 && IntStream.range(2, number).noneMatch( record - > number % file == 0); }

    IntStream is an arrangement of crude int-esteemed components supporting successive and parallel total tasks. This is the int crude specialization of Stream.

    For greater comprehensibility, we can likewise compose the technique like below.

    private static boolean isPrime(int number) { IntPredicate isDivisible = file - > number % record == 0; return number > 1 && IntStream.range(2, number).noneMatch( isDivisible); }

    If you are inexperienced with IntStream, it's range() technique restores a successive arranged IntStream from startInclusive (comprehensive) to endExclusive (select) by a gradual advance of 1.

    noneMatch() technique returns whether no components of this stream coordinate the gave predicate. It may not assess the predicate on all components if a bit much to decide the outcome.

  3. Passing Behaviors into methods

    Let's perceive how we can utilize lambda articulations to pass conduct of a strategy with a straightforward precedent. Suppose we need to compose a strategy to entirety the numbers in a rundown in the event that they coordinate a given criteria. We can utilize Predicate and compose a technique like below.

    public static int sumWithCondition(List<Integer> numbers, Predicate<Integer> predicate) { 
    return numbers.parallelStream() 
    .mapToInt(i - > I) 

    Sample usage:

    //sum of all numbers 
    sumWithCondition(numbers, n - > true) 
    //sum of every significantly number 
    sumWithCondition(numbers, I - > i%2==0) 
    //sum of all numbers more noteworthy than 5 
    sumWithCondition(numbers, I - > i>5) 
  4. Higher Efficiency with Laziness

    One more preferred standpoint of utilizing lambda articulation is the lethargic assessment, for instance suppose we have to work a strategy to discover the most extreme odd number in the range 3 to 11 and return square of it.

    Usually we will compose code for this technique like this:

    private static int findSquareOfMaxOdd(List<Integer> numbers) { 
    int max = 0; 
    for (int I : numbers) { 
    if (I % 2 != 0 && I > 3 && I < 11 && I > max) { 
    max = I; 
    return max * max; 

    Above program will dependably keep running in consecutive request however we can utilize Stream API to accomplish this and get advantage of Laziness-chasing. How about we perceive how we can modify this code in useful programming way utilizing Stream API and lambda expressions.

    public static int findSquareOfMaxOdd(List<Integer> numbers) { return numbers.stream() .filter(NumberTest::isOdd) //Predicate is utilitarian interface and .filter(NumberTest::isGreaterThan3) //we are utilizing lambdas to introduce it .filter(NumberTest::isLessThan11) //as opposed to unknown inward classes .max(Comparator.naturalOrder()) .map(i - > I * I) .get(); } public static boolean isOdd(int i) { return I % 2 != 0; } public static boolean isGreaterThan3(int i){ return I > 3; } public static boolean isLessThan11(int i){ return I < 11; }

    If you are amazed with the twofold colon (::) administrator, it's presented in Java 8 and utilized for method references. Java Compiler deals with mapping the contentions to the called technique. It's short type of lambda articulations i - > isGreaterThan3(i) or i - > NumberTest.isGreaterThan3(i).

Lambda Expression Examples

Below I am providing some code snippets for lambda expressions with small comments explaining them.

() -> {} // No parameters; void result () -> 42 // No parameters, expression body () -> null // No parameters, expression body () -> { return 42; } // No parameters, block body with return () -> { System.gc(); } // No parameters, void block body // Complex block body with multiple returns () -> { if (true) return 10; else { int result = 15; for (int i = 1; i < 10; i++) result *= i; return result; } } (int x) -> x+1 // Single declared-type argument (int x) -> { return x+1; } // same as above (x) -> x+1 // Single inferred-type argument, same as below x -> x+1 // Parenthesis optional for single inferred-type case (String s) -> s.length() // Single declared-type argument (Thread t) -> { t.start(); } // Single declared-type argument s -> s.length() // Single inferred-type argument t -> { t.start(); } // Single inferred-type argument (int x, int y) -> x+y // Multiple declared-type parameters (x,y) -> x+y // Multiple inferred-type parameters (x, final y) -> x+y // Illegal: can't modify inferred-type parameters (x, int y) -> x+y // Illegal: can't mix inferred and declared types

Method and Constructor References

A strategy reference is utilized to allude to a technique without summoning it; a constructor reference is likewise used to allude to a constructor without making another occasion of the named class or cluster type.

Examples of strategy and constructor references:







That's supportive of Java 8 Functional Interfaces and Lambda Expression Tutorial. I would unequivocally propose to investigate utilizing it since this sentence structure is new to Java and it will require some investment to get a handle on it.

journaldev is optimized for learning.© journaldev .
All Right Reserved and you agree to have read and accepted our term and condition