Interview Questions & Answers

java

Method reference is used to refer method of the 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 a method reference.

Below are a few examples of method reference:

(o) -> o.toString();

can become:

Object::toString();

Static method reference:

String::valueOf;

Bound instance method reference:

str::toString;

Unbound instance method reference:

String::toString;

In Java 8, there are a lot of functional interfaces are introduced in the java.util.function package and the more common ones include but are not limited to:
  • Function – it takes one argument and returns a result
  • Consumer – it takes one argument and returns no result (represents a side effect)
  • Supplier – it takes no argument and returns a result
  • Predicate – it takes one argument and returns a boolean
  • BiFunction – it takes two arguments and returns a result
  • BiConsumer – it takes two (reference type) input arguments and returns no result
  • BinaryOperator – it is similar to a BiFunction, taking two arguments and returning a result. The two arguments and the result are all of the same types
  • UnaryOperator – it is similar to a Function, taking a single argument and returning a result of the same type
  • Runnable: use to execute the instances of a class over another thread with no arguments and no return value.
  • Callable: use to execute the instances of a class over another thread with no arguments and it either returns a value or throws an exception.
  • Comparator: use to sort different objects in a user-defined order
  • Comparable: use to sort objects in the natural sort order.

Yes, it is possible to define our own Functional Interfaces. We use Java 8 provides the @FunctionalInterface annotation to mark an interface as a Functional Interface.
We need to follow these rules to define a Functional Interface:
  • Define an interface with one and only one abstract method.
  • We cannot define more than one abstract method.
  • Use @FunctionalInterface annotation in the interface definition.
  • We can define any number of other methods like default methods, static methods.
The below example illustrates defining our own Functional Interface:
Let’s create a Sayable interface annotated with @FunctionalInterface annotation.
@FunctionalInterface
interface Sayable{
    void say(String msg);   // abstract method   
} 

Let's demonstrate a custom functional interface via the main() method.
public class FunctionalInterfacesExample {

    public static void main(String[] args) {

        Sayable sayable = (msg) -> {
            System.out.println(msg);
        };
        sayable.say("Say something ..");
    }
}

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. It can also declare the methods of the object class.
Functional Interface is also known as Single Abstract Method Interfaces or SAM Interfaces. A functional interface can extend another interface only when it does not have any abstract method.
Java 8 provides predefined functional interfaces to deal with functional programming by using lambda and method references.
Example:
interface Printable {
    void print(String msg);
}

public class JLEExampleSingleParameter {

    public static void main(String[] args) {
        // with lambda expression
        Printable withLambda = (msg) -> System.out.println(msg);
        withLambda.print(" Print message to console....");
    }
}

output:
Print message to console....
 

Java Lambda Expression Syntax:

(argument-list) -> {body}
Java lambda expression consists of three components.
  • Argument-list: It can be empty or non-empty as well.
  • Arrow-token: It is used to link arguments-list and body of expression.
  • Body: It contains expressions and statements for the lambda expression.

For example, Consider we have a functional interface:

interface Addable{
    int add(int a,int b);
} 
Let's implement the above Addable functional interface using a lambda expression:
Addable withLambdaD = (int a,int b) -> (a+b);  
    System.out.println(withLambdaD.add(100,200));

  1. Facilitates functional programming – Lambda Expression facilitates functional programming and simplifies the development a lot.
  2. To provide the implementation of the Java 8 Functional Interface.
  3. Reduced Lines of Code – One of the clear benefits of using lambda expression is that the amount of code is reduced, we have already seen that how easily we can create instances of a functional interface using lambda expression rather than using an anonymous class.
  4. Passing Behaviors into methods – Lambda Expressions enable you to encapsulate a single unit of behavior and pass it to other code. For example, to other methods or constructors.

In Java 8,  the following new features were added:
  • Lambda Expressions − lambda expression is a function that can be referenced and passed around as an object
  • Method References − Method references are the references that use a function as a parameter to request a method.
  • Optional − This class is to provide a type-level solution for representing optional values instead of using null references.
  • Functional Interface – An Interface that contains exactly one abstract method and implementation can be provided using a Lambda Expression
  • Default methods − give us the ability to add full implementations in interfaces besides abstract methods
  • Stream API − Stream API provides a functional approach to processing collections of objects.
  • Date and Time API − an improved, immutable JodaTime-inspired Date API
  • Nashorn, JavaScript Engine − Java-based engine for executing and evaluating JavaScript code
Along with these new features, lots of feature enhancements are done under-the-hood, at both compiler and JVM levels.