Java - Lambda Constructor References

Syntax

The syntax for using a constructor is

ClassName::new
ArrayTypeName::new

ClassName::new is the name of the class that can be instantiated; it cannot be the name of an abstract class.

The keyword new refers to the constructor of the class.

The syntax does not provide a way to refer to a specific constructor.

The compiler selects a specific constructor based on the context.

The constructor's number of arguments matches the number of arguments in the abstract method of the target type.

Constructor References are for an object creation expression.

The following two statements that use a String object creation expression as the body for lambda expressions:

Supplier<String> func1 = () -> new String();
Function<String,String> func2 = str -> new String(str);

You can rewrite these statements by replacing the lambda expressions with constructor references as shown:

Supplier<String> func1 = String::new;
Function<String,String> func2 = String::new;

Exaple

The following code uses three constructors of the Product class:

Supplier<Product> func1 = () -> new Product();
Function<String,Product> func2 = name -> new Product(name);
BiFunction<String,Double, Product> func3 = (name, price) -> new Product(name, price);

System.out.println(func1.get());
System.out.println(func2.apply("Apple"));
System.out.println(func3.apply("Apple", 0.75));
The following code replaces the lambda expressions with a constructor reference Product::new. 
Supplier<Product> func1 = Product::new;
Function<String,Product> func2 = Product::new;
BiFunction<String,Double, Product> func3 = Product::new;

The following statement generates a compile-time error, as the compiler does not find a constructor in the Product class that accepts a Double argument:

Function<Double,Product> func4 = Product::new; // A compile-time error

Demo

import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

interface Priced {
  default double getPrice() {
    return 1.0;/*w  w  w.j  av  a2 s. co m*/
  }
}

class Product implements Priced {
  private String name = "Unknown";
  private double price = 0.0;

  public Product() {
    System.out.println("Constructor Product() called.");
  }

  public Product(String name) {
    this.name = name;
    System.out.println("Constructor Product(String) called.");
  }

  public Product(String name, double price) {
    this.name = name;
    this.price = price;
    System.out.println("Constructor Product(String, double) called.");
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public void setPrice(double price) {
    this.price = price;
  }

  @Override
  public double getPrice() {
    return price;
  }

  @Override
  public String toString() {
    return "name = " + getName() + ", price = " + getPrice();
  }

}
public class Main {
  public static void main(String[] args) {
    Supplier<Product> func1 = Product::new;
    Function<String,Product> func2 = Product::new;
    BiFunction<String,Double, Product> func3 = Product::new;
    
    System.out.println(func1.get());
    System.out.println(func2.apply("book2s.com"));
    System.out.println(func3.apply("Java", 0.75));
  }
}

Result

Related Topics