Understand the usage of double colon " :: " in Java8, method reference character

When using lambda expressions, the code we actually pass in is a solution: what to do with what parameters. Imagine that there is such a situation: the operation scheme we specified in Lambda already has the same scheme, so is it necessary to rewrite the logic?

Of course you don't need to. At this time, what we are going to explain today is used: Java's method reference character "::".

// Lambda 表达式写法:
s -> System.out.println(s);
// :: 方法引用写法:
System.out::println

We can use the existing scheme through method references to make expressions more concise.


text

In Java 8, the double colon :: is called "method reference operator", the :: symbol is a reference operator, and the expression in which it is located is called a method reference, and we can use it to refer to a method of a class.

:: refers to a method of a class and returns a function interface ( function interface ), which is equivalent to a lambda expression, but different from a lambda expression, a lambda expression needs to customize a lambda body, while :: refers to a method .

/**
* 表示接受一个参数并生成结果的函数。
* @param<T>函数的输入类型
* @param<R>函数结果的类型
* @从1.8开始
*/
@FunctionalInterface
public interface Function<T, R> {
     R apply(T t);

    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    static <T> Function<T, T> identity() {
        return t -> t;
    }
}

There are four types of method reference operators:

  1. ClassName :: New : a reference to the constructor, equivalent to creating an object;
  2. ClassName :: static_method : If there are parameters, the parameters will be used as the actual parameters of the method;
  3. ClassName :: instance_method : The first parameter is used as a class object to call instance_method, and other parameters are used as method parameters;
  4. instance :: instance_method : If there are parameters, the parameters will be used as the actual parameters of the method;

case

Below, a brief demonstration of the use of the four types of Java references:

import java.util.Arrays;
import java.util.Optional;
import java.util.function.Supplier;

/** 引用操作符的四种类型 */
public class JavaTest {

    public static class User {
        private String id;
        private Integer age;
        private String name;

        // ... 省略了参数的get(),set()方法

        @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder("User{");
            sb.append("id='").append(id).append('\'');
            sb.append(", age=").append(age);
            sb.append(", name='").append(name).append('\'');
            sb.append('}');
            return sb.toString();
        }

        public static void testStatic(String s){
            System.out.println(s);
        }
    }

    /**
     * 1.构造器引用
     *   ClassName::New => new ClassName()
     *   如果调用时有参数,相当于调用带参的构造函数
     */
    @Test
    public void test1(){
        App.toString(User::new);
    }
    public static void toString(Supplier supplier){
        System.out.println(supplier.get().toString());
    }

    /**
     * 2.静态方法引用
     *   ClassName::static_method =》 CLassName.static_method()
     *   如果调用时有参数,直接放到静态方法的形参中
     */
    @Test
    public void test2(){
        Arrays.asList("name1","name2").stream().forEach(User::testStatic);
    }

    /**
     * 3.特定类对方法引用
     *   ClassName::instance_method => obj.instance_method(xxx)
     *   调用时参数:第一个参数是实体对象 上面的obj
     *   如果有其他参数,会传到方法中
     */
    @Test
    public void test3(){
        User user = new User();
        user.setId("625");
        user.setAge(30);
        user.setName("java punk");
        Optional.of(user).ifPresent(User::toString);
    }

    /**
     * 4.特定对象对方法引用
     *   instance::instance_method =》instance.instance_method(xxxx);
     *   如果有参数,参数就是方法的参数
     */
    @Test
    public void test4(){
        User user = new User();
        user.setId("625");
        user.setAge(30);
        user.setName("java punk");
        toString(user::toString);
    }
}

Guess you like

Origin blog.csdn.net/weixin_44259720/article/details/122680270