Method references to new JDK 1.8 features:: and Optional details

  • 2021-11-13 01:39:43
  • OfStack

1: Introduction

Method references are divided into three types. Method references are represented by a pair of double colons::, and method references are another way to write a functional interface

Static method reference, via class name:: static method name, such as Integer:: parseInt Instance method reference, through instance object:: instance method, such as str:: substring Construct a method reference by class name:: new, such as User:: new

2: Method references


public final class Integer {
    public static int parseInt(String s) throws NumberFormatException {
        return parseInt(s,10);
    }
}

Through method reference, you can assign a method reference to a variable, and by assigning a value to Function, it shows that method reference is also a writing mode of functional interface, Lambda expression is also a functional interface, Lambda expression 1 is generally used to provide its own method body, while method reference 1 directly refers to existing methods.


public class User {
    private String username;
    private Integer age;

    public User() {
    }

    public User(String username, Integer age) {
        this.username = username;
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", age=" + age +
                '}';
    }

    // Getter&Setter
}    

public static void main(String[] args) {
    //  Use double colons :: To construct static function references 
    Function<String, Integer> fun = Integer::parseInt;
    Integer value = fun.apply("123");
    System.out.println(value);

    //  Use double colons :: To construct non-static function references 
    String content = "Hello JDK8";
    Function<Integer, String> func = content::substring;
    String result = func.apply(1);
    System.out.println(result);

    //  Constructor reference 
    BiFunction<String, Integer, User> biFunction = User::new;
    User user = biFunction.apply("mengday", 28);
    System.out.println(user.toString());

    //  Function references are also 1 Functional interface, so you can also take function references as parameters of methods 
    sayHello(String::toUpperCase, "hello");
}

//  Method takes two parameters, 1 One is 
private static void sayHello(Function<String, String> func, String parameter){
    String result = func.apply(parameter);
    System.out.println(result);
}

3: Optional Optional

There is Optional in Google Guava, and there is such a similar syntax in Swift language. In Swift, optional value is regarded as a data type, and its status is flush with that of basic type, which is very high.


package java.util;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * @since 1.8
 */
public final class Optional<T> {
    private static final Optional<?> EMPTY = new Optional<>();

    private final T value;

    private Optional() {
        this.value = null;
    }

    //  Return 1 Empty  Optional Instances 
    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }

    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }

    //  Returns a  Optional Of the current non-null value of Optional
    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }

    //  Return 1 A  Optional Object for the specified value Optional If it is not empty, it returns 1 Empty  Optional
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }

    //  If Optional Among them 1 Returns a value, otherwise throws  NoSuchElementException  . 
    public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }

    //  Return true If there is a value, otherwise; Otherwise  false 
    public boolean isPresent() {
        return value != null;
    }

    //  If there is a value, the specified consumer is called with the value, otherwise nothing is done. 
    public void ifPresent(Consumer<? super T> consumer) {
        if (value != null)
            consumer.accept(value);
    }

    //  If 1 Returns when a value exists and the predicate given by the value matches 1 A  Optional Otherwise, return the value described by the 1 Empty  Optional
    public Optional<T> filter(Predicate<? super T> predicate) {
        Objects.requireNonNull(predicate);
        if (!isPresent())
            return this;
        else
            return predicate.test(value) ? this : empty();
    }

    //  If it exists 1 Value, the provided mapping function is applied, and if the result is not empty, it returns 1 A  Optional Resultant  Optional  . 
    public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();
        else {
            return Optional.ofNullable(mapper.apply(value));
        }
    }

    //  If 1 Values exist, and the provided value is applied  Optional Map the function to it and return the result, otherwise return 1 Empty  Optional  . 
    public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();
        else {
            return Objects.requireNonNull(mapper.apply(value));
        }
    }

    //  Returns a value if it exists, and another specified value if it does not exist 
    public T orElse(T other) {
        return value != null ? value : other;
    }


    public T orElseGet(Supplier<? extends T> other) {
        return value != null ? value : other.get();
    }

    public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
        if (value != null) {
            return value;
        } else {
            throw exceptionSupplier.get();
        }
    }   
}

As for the of method, it seems very popular now, that is, to provide an static method with the name of of, the return value of the method returns to the current class, and set the constructor to private private, replacing the constructor with a static of method.


public class User {
    private String username;
    private Integer age;

    private User() {
    }

    public static User of() {
        return new User();
    }

    private User(String username, Integer age) {
        this.username = username;
        this.age = age;
    }

    public static User of(String username, Integer age) {
        return new User(username, age);
    }
}

Main


public static void main(String[] args) {
    // Optional Class has become Java 8 Class library 1 Part, in Guava It's been around for a long time, maybe Oracle It is directly used 
    // Optional Used to solve the null pointer exception, make the code more rigorous, and prevent the null pointer from being used NullPointerException Impact on code 
    String msg = "hello";
    Optional<String> optional = Optional.of(msg);
    //  Determine whether there is a value, which is not empty 
    boolean present = optional.isPresent();
    //  If there is a value, the value is returned, and if it is equal to null, an exception is thrown 
    String value = optional.get();
    //  If it is empty, return else The specified value 
    String hi = optional.orElse("hi");
    //  If the value is not empty, execute Lambda Expression 
    optional.ifPresent(opt -> System.out.println(opt));
}

Related articles: