Java Lambda - Java Static Method Reference








A lambda expression represents an anonymous function defined in a functional interface.

A method reference creates a lambda expression using an existing method.

The general syntax for a method reference is

Qualifier::MethodName

Two consecutive colons act as a separator.

The MethodName is the name of the method.

Qualifier tells where to find the method reference.

Example

For example we can use String::length to reference the length method from String class. Here String is the qualifier and length is the method name.

We only need to specify the method name.

There is no need to specify the parameter types and return type for the method.

The target type of the method reference is a functional interface. It determines the method's signature and resolves the overloaded method if necessary.





Types of Method References

There are six types of method reference.

  • TypeName::staticMethod - reference to a static method of a class, an interface, or an enum
  • objectRef::instanceMethod - reference to an instance method
  • ClassName::instanceMethod - reference to an instance method from a class
  • TypeName.super::instanceMethod - reference to an instance method from the supertype of an object
  • ClassName::new - reference to the constructor of a class
  • ArrayTypeName::new - reference to the constructor of the specified array type




Static Method References

A static method reference allows us to use a static method as a lambda expression.

The static methods can be defined in a class, an interface, or an enum.

The following code defines two lambda expressions.

The first lambda expression func1 is created by defining an input parameter x and providing lambda expression body. Basically it is the normal way of creating a lambda expression.

The second lambda expression func2 is created by referencing a static method from Integer class.

import java.util.function.Function;
//from  w  w w  .  ja v a  2  s  .  c  om
public class Main {
  public static void main(String[] argv) {
    // Using  a  lambda  expression
    Function<Integer, String> func1  = x -> Integer.toBinaryString(x);
    System.out.println(func1.apply(10));

    // Using  a  method  reference
    Function<Integer, String> func2  = Integer::toBinaryString;
    System.out.println(func2.apply(10));
  }  
}

The signature of the static method from the Integer class is as follows.

static String toBinaryString(int i)

The code above generates the following result.

Example 2

The following code shows how to use the Integer.sum as lambda expression.

import java.util.function.BiFunction;
//w  ww  .j a v a 2 s. c o m
public class Main {
  public static void main(String[] argv) {

    // Uses a lambda expression
    BiFunction<Integer, Integer, Integer> func1 = (x, y) -> Integer.sum(x, y);
    System.out.println(func1.apply(2, 3));

    // Uses a method reference
    BiFunction<Integer, Integer, Integer> func2 = Integer::sum;
    System.out.println(func2.apply(2, 3));

  }
}

The code above generates the following result.

Static Method References in Overloading

We can use overloaded static method in static method reference.

When the overloaded method we have to pay more attention to the method signature and corresponding functional interface.

In the following list we have three versions of the valueOf() from the Integer class.

static Integer valueOf(int i)
static Integer  valueOf(String s)
static Integer  valueOf(String s, int radix)

The following code shows how different target functional interfaces can be used with the overloaded the Integer.valueOf() static methods.

import java.util.function.BiFunction;
import java.util.function.Function;
/*from w  w w . j a v a 2s .co m*/
public class Main{
  public static void main(String[] argv){
    // Uses  Integer.valueOf(int)
    Function<Integer, Integer> func1  = Integer::valueOf;

    // Uses  Integer.valueOf(String)
    Function<String, Integer> func2  = Integer::valueOf;

    // Uses  Integer.valueOf(String, int)
    BiFunction<String, Integer,  Integer> func3  = Integer::valueOf;

    System.out.println(func1.apply(7)); 
    System.out.println(func2.apply("7")); 
    System.out.println(func3.apply("101010101010", 2));
  }
}

The code above generates the following result.