Blog Java OCAJP 8 – Lambda Expressions Examples

OCAJP 8 – Lambda Expressions Examples

In this post we are going to explain about one of the important feature in Java 8 Lambda Expressions. This feature is also included in the OCAJP 8 Java certification exam. You should have enough understanding on the concepts and practice to answer all the questions in the real exam. Our OCAJP 8 exam simulator covers more questions with lambda expressions.

What is Lambda Expression?

  • Lamdba Expressions is the new feature introduced in JDK 8 .
  • lambda expressions (and their related features) significantly enhance Java because of two primary reasons.
  • First, they add new syntax elements that increase the expressive power of the language.
  • Second, the addition of lambda expressions resulted in new capabilities being incorporated into the API library.
  • Beyond the benefits that lambda expressions bring to the language, there is another

Reason why they constitute an important addition to Java. Over the past few years, lambda expressions have become a major focus of computer language design. For example, they have been added to languages such as C# and C++.

  • You need to know what is functional interface before going to learn about Lamdba Expressions.

What is Functional Interface?

  • Functional interface is an interface which contains only one abstract method and may contain any number of default and static methods (default and static methods are allowed in interfaces since Java 8 ).

Example:

interface MyNumber {
getValue( );
}

  • Here MyNumber is a Functional interface because it contains one abstract method.
  • Let’s look at another example

Example:

interface MyValue {
getValue( );
printValue( );
}
  • MyValue is not a Functional interface because it contains two abstract methods.

Example:

interface Sample {
print( );
static void sayHello() {
System.out.println("Hello World " );
} }
  • Sample is a functional interface because it contains only one abstract method.

Lambda Expressions

  • A lambda expression is an anonymous (that is, unnamed) method.
  • It is used to implement a method defined by a functional interface.
  • A lambda expression is assigned to functional interface reference .
  • Lambda expression is not executed on its own.
  • When you call functional interface method with interface reference then Lambda expression will be executed.
  • Thus a lambda expression results in a form of anonymous class.
  • Lambda expressions are also commonly referred to as closures.
  • The lambda expression introduces a new syntax element and operator into the Java language.
  • The new operator sometimes referred to as the lambda operator or the arrow operator that is −>.
  • It divides a lambda expression into two parts. The left side specifies any parameters required

by the lambda expression. (If no parameters are needed, an empty parameter list is used.) On the right side is the lambda body, which specifies the actions of the lambda expression.

  • Java defines two types of lambda bodies. One consists of a single expression and the other type consists of a block of code.
  • Let’s write first lambda example.
    	
    interface MyNumber {
    	int getValue();
    }
    public class SupplyDemo {
    public static void main(String[] args) {
    MyNumber num1 = () -> 9;
    MyNumber num2 = () -> { return 5; };
    System.out.println(num1.getValue()); //prints 9
    System.out.println(num2.getValue()); //prints 5
    
    }
    }
    
  • When you are writing lambda expression first look at functional interface method declaration.
  • getValue doesn’t take any parameters. So parenthesis are mandatory.
  • When functional interface method doesn’t take any parameters then parenthesis are mandatory in the parameter list of lambda expression.
  • Look at functional interface method return type. It returns int. So our lambda expression should return int value.
  • If lambda expression contains only one statement,curly braces are optional. If lambda expression contains only more than one statement,curly braces are mandatory .
  • When lambda expression contains only one statement that will be returned by the lambda expression by default.
  • Lambda expression should end with semicolon even it contains more than one statement.
  • Using Lambda expression , you can write multiple implementations to the functional interface method.But it should compatible with the method declaration.
  • When you call num1.getValue( ), Lambda expression will be executed and returns value 9.
  • When you call num2.getValue( ), Lambda expression will be executed and returns value 5.
  • Let’s understand another example
    	
    interface NumericTest {
    boolean test(int n);
    }
    class LambdaDemo2 {
    
    public static void main(String args[])
    {
    
    // A lambda expression that tests if a number is even.
    NumericTest isEven = (n) -> (n % 2)==0;
    
    if(isEven.test(10)) System.out.println("10 is even");
    
    if(!isEven.test(9)) System.out.println("9 is not even");
    
    // Now use a lambda expression that tests if a number
    // is non-negative.
    NumericTest isNonNeg = (n) -> n >= 0;
    
    if(isNonNeg.test(1)) System.out.println("1 is non-negative");
    if(!isNonNeg.test(-1)) System.out.println("-1 is negative");
    }
    }
    
  • The output from this program is shown here:

10 is even

9 is not even

1 is non-negative

-1 is negative

  • Pay special attention to the lambda expression that performs the test for evenness. It is shown again here:

(n) -> (n % 2)==0

  • Notice that the type of n is not specified. Rather, its type is inferred from the context.
  • In this case, its type is inferred from the parameter type of test( ) as defined by the NumericTest interface, which is int.
  • It is also possible to explicitly specify the type of a parameter in a lambda expression. For example, this is also a valid way to write the preceding:

(int n) -> (n % 2)==0

  • Here n is explicitly specified as int. Usually it is not necessary to explicitly specify the type but you can in those situations that require it.
  • When a lambda expression has only one parameter , it is not necessary to surround the parameter name with parentheses when it is specified on the left side of the lambda operator.
  • For example, this is also a valid way to write the lambda expression used in the program:

n -> (n % 2)==0

  • The next program demonstrates a lambda expression that takes two parameters. In this case, the lambda expression tests if one number is a factor of another.

// Demonstrate a lambda expression that takes two parameters.

interface NumericTest2 {
boolean test(int n, int d);
}

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

// This lambda expression determines if one number is
// a factor of another.
NumericTest2 isFactor = (n, d) -> (n % d) == 0;
if(isFactor.test(10, 2))
System.out.println("2 is a factor of 10");
if(!isFactor.test(10, 3))
System.out.println("3 is not a factor of 10");
}
}

The output is shown here:

2 is a factor of 10

3 is not a factor of 10

  • In this program, the functional interface NumericTest2 defines the test( ) method:

boolean test(int n, int d);

  • In this version, test( ) specifies two parameters. Thus, for a lambda expression to be compatible with test( ), the lambda expression must also specify two parameters. Notice

how they are specified:

(n, d) -> (n % d) == 0

  • Whenever more than one parameter is required, the parameters are specified, separated by commas, in a parenthesized list on the left side of the lambda operator.
  • Here is an important point about multiple parameters in a lambda expression: If you need to explicitly declare the type of a parameter, then all of the parameters must have declared types. For example, this is legal:

(int n, int d) -> (n % d) == 0

  • But this is not:

(int n, d) -> (n % d) == 0

Predicate

  • Predicate is a predefined functional interface which is available in java.util.function package. It is a generic type.

  • Predicate is listed in OCAJP 8 exam objectives.

  • A lambda expression, itself, cannot specify type parameters. Thus, a lambda expression cannot be generic. (Of course, because of type inference, all lambda expressions exhibit some “generic-like” qualities.)
  • However, the functional interface associated with a lambda expression can be generic. In this case, the target type of the lambda expression is determined, in part, by the type argument or arguments specified when a functional interface reference is declared.

public interface Predicate {
boolean test(T t);

}

  • Predicate method takes instance of any class and returns boolean value.
  • Let’s see sample example which uses Predicate
public class PredicateDemo {
public static void main(String[] args) {
Predicate start = s -> s.startsWith("O");
System.out.println(start.test("OCAJP8")); // prints true
}
}

Passing Lambda Expressions as Arguments

  • In fact, passing a lambda expression as an argument is a common use of lambdas. Moreover, it is a very powerful use because it gives you a way to pass executable code as an argument to a method.
  • This greatly enhances the expressive power of Java.
  • To pass a lambda expression as an argument, the type of the parameter receiving the lambda expression argument must be of a functional interface type compatible with the lambda expression.

Example:

public class PredicateDemo {
public static void main(String[] args) {
call(s -> s.startsWith("O"),"OCAJP8");
}
public static void call(Predicate <String> start, String l) {
boolean b = start.test(l)?true : false ;
System.out.println(b); // prints true
}
}

Lambda Expressions and Exceptions

  • A lambda expression can throw an exception. However, it if throws a checked exception, then that exception must be compatible with the exception(s) listed in the throws clause of the abstract method in the functional interface. Here is an example that illustrates this fact.
class NotValidString extends Exception{}
interface Sample{
void print(T t) throws NotValidString;
}
public class Test {

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

Sample l = s->{

if(s.length()==0)
throw new NotValidString();
else
System.out.println(s);

};


l.print("OCA");
l.print(" ");

}

}

The first call to l.print(“OCA”) prints the value OCA. The second call, which passes a zero-length string , causes an NotValidString exception to be thrown. Remember, the inclusion of the throws clause in print is necessary. Without it, the program will not compile because the lambda expression will no longer be compatible with print( ).

Lambda Expressions and Variable Capture

  • Variables defined by the enclosing scope of a lambda expression are accessible within the lambda expression. For example, a lambda expression can use an instance or static variable defined by its enclosing class.
  • Thus, a lambda expression can obtain or set the value of an instance or static variable and call a method defined by its enclosing class.
  • However, when a lambda expression uses a local variable from its enclosing scope, a special situation is created that is referred to as a variable capture.
  • In this case, a lambda expression may only use local variables that are effectively final.
  • An effectively final variable is one whose value does not change after it is first assigned.
  • There is no need to explicitly declare such a variable as final, although doing so would not be an error.
interface Sample {
int sum(int t);
}

public class PredicateDemo {

public static void main(String[] args) {
int b = 5;
Sample l = a -> {

int c = a + b;

// the following commented statement causes error if uncommented
// b++;
return c;

};
// the following commented statement causes error if uncommented
// b=6;

System.out.println(l.sum(10));//prints 15
}

}
  • As the comments indicate, b is effectively final and can, therefore, be used inside Lambda expression.
  • However, if b were to be modified, either inside the lambda or outside of it, b would lose its effectively final status. This would cause an error, and the program would not compile.

We hope this article would be useful for understanding the Lambda expressions that are used in the OCAJP 8 exam. Please try our free mock exam for OCAJP 8.

If you require any help or support for preparing the OCAJP exam, please send us a mail or call to our support number!!.

About Aditi Malhotra

Aditi Malhotra is the Content Marketing Manager at Whizlabs. Having a Master in Journalism and Mass Communication, she helps businesses stop playing around with Content Marketing and start seeing tangible ROI. A writer by day and a reader by night, she is a fine blend of both reality and fantasy. Apart from her professional commitments, she is also endearing to publish a book authored by her very soon.

LEAVE A REPLY

Please enter your comment!
Please enter your name here