Java8 - Method References

Method references simplify lambda expressions by referencing existing methods with class or method names. So when do I need to use a method reference? If the content in the lamdba body is already implemented by a method, we can use a method reference.

1. Three Grammatical Formats for Method References

1. Object: Instance method name

lamdba notation:

@Test
void test1(){
    Consumer<String> con = x -> System.out.println(x);
}

Method Reference Writing:

@Test
void test2(){
    PrintStream out = System.out;
    Consumer<String> con = out::println;
}

consumer interface:

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}

Note: The parameter list and return value type of the method being invoked need to be consistent with the parameter list and return value type of the abstract method in the functional interface.

2. Class:: Static method name

lamdba notation:

@Test
void test3(){
    Comparator<Integer> com = (x, y) -> Integer.compare(x,y);
}

Method Reference Writing:

@Test
void test4(){
    Comparator<Integer> com = Integer::compare;
}

Comparator interface:

@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);
}

Integer class section:

public final class Integer extends Number implements Comparable<Integer> { 
	public static int compare(int x, int y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }
}

Note: The parameter list and return value type of the method being invoked need to be consistent with the parameter list and return value type of the abstract method in the functional interface.

3. Class:Instance method name

lamdba notation:

@Test
void test5(){

    BiPredicate<String,String> bp = (x,y) -> x.equals(y);
}

Method Reference Writing:

@Test
void test6(){
    BiPredicate<String,String> bp = String::equals;
}

BiPredicate interface:

@FunctionalInterface
public interface BiPredicate<T, U> {
    boolean test(T t, U u);
}

Note: The first parameter is the caller of this instance method, and the second parameter is the parameter of this instance method, so this syntax can be used.

2. Constructor References

Class:new

lamdba notation:

@Test
void test7(){
    Supplier<Person> supplier = ()->new Person();
}

Constructor applies writing:

@Test
void test8(){
    Supplier<Person> supplier = Person::new;
}

Supplier interface:

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

Person class:

@Data
public class Person implements Serializable {
    private static final long serialVersionUID = -7008474395345458049L;

    private String name;
    private int age;

    public Person() {
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

Note that there are two constructors in the person class, and which one to call is determined by the functional interface, that is, the get() method in the Supplier interface is parameterless, then the parameterless constructor in person is called.

3. Array References

Type::new

lamdba notation:

@Test
void test9(){
    Function<Integer,String[]> fun = x -> new String[x];
}

Array Reference Writing:

@Test
void test10(){
    Function<Integer, String[]> fun = String[]::new;
}

Function interface section:

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}

summary

  • Method applications and constructor references can actually be understood as another form of lamdba
  • The method reference parameter list and return value type of the invoked method need to be consistent with the parameter list and return value type of the abstract method in the functional interface
  • Use classes in method references:The condition for an instance method is that the first parameter is the caller of the instance method and the second parameter is the parameter of the instance method
  • The argument list of constructor references to constructors that need to be invoked should be consistent with the argument list of abstract methods in functional interfaces

Tags: Java

Posted by lalov1 on Tue, 31 May 2022 05:12:04 +0530