Lambda expressions are an important new feature in Java 8, and it is important for us Java developers to learn how to use lambda.

This article will take you to quickly learn and master the use of lambda expressions and functional programming

Quick Start

Lambda expressions can be used in two places:

  1. Create anonymous inner classes
  2. Create an object

Let’s go straight to the code

== Create an anonymous inner class ==

public static void main(String[] args) {
    // Create anonymous inner classes using lambda expressions
    Thread thread = new Thread(() -> {
        System.out.println("Run!");
    });
    // The following are optimizations
    Since there is only one line of code, lambda expressions can be optimized
    Thread thread = new Thread(() -> System.out.println("Run!");
}
Copy the code

== Create an object ==

public static void main(String[] args) {
    // I'm using the Integer object directly. You can create your own object instead
    Comparator<Integer> comparator = (Integer n1, Integer n2) -> {returnn1 - n2; };// Apple has two attributes: name(String) and weight(int)
    Comparator<Apple> comparatorApple = (Apple a1, Apple a2) -> {returna1.getWeight() - a2.getWeight(); };// In fact, type derivation can be used for optimization
    Comparator<Integer> comparator = (n1, n2) -> {returnn1 - n2; }; Comparator<Apple> comparatorApple = (a1, a2) -> {returna1.getWeight() - a2.getWeight(); };// Further, since there is only one line
    Comparator<Integer> comparator = (n1, n2) -> n1 - n2;
    Comparator<Apple> comparatorApple = (a1, a2) -> a1.getWeight() - a2.getWeight();
    
    // Since Integer comes with its own comparison method, we can optimize again using method references
    Comparator<Integer> comparator = Integer::compareTo;
}
Copy the code

How about lambda expressions?

I believe you have also seen my code optimization, which involves further learning of lambda expressions, reference

reference

Method references

We can use method references and constructor references, and the code above shows what a method reference is,

Comparator<Integer> comparator = Integer::compareTo;
Copy the code

To show you what the code looks like without using method references,

Comparator<Integer> comparator = (n1, n2) -> n1.compareTo(n2);
Copy the code

As you can see, it will automatically substitute variables based on our input parameters by default, at which point someone will ask if the result of the comparison is in ascending or descending order using the comparator referenced by the method. It’s all set up for you here.

Comparator<Integer> comparator = Integer::compareTo;
List<Integer> list = Arrays.asList(5.4.3.2.1);
list.sort(comparator);
System.out.println(list);
// Result [1, 2, 3, 4, 5]
Copy the code

As you can see, the default is ascending.

Constructor reference

Constructor references are easier to understand if you can understand method references, but when you create an object that is a functional interface, you can use constructor references, so let’s move on to the code.

Supplier, a functional interface that comes with Java, is used

/ / the original
Supplier<Apple> supplier = new Supplier<Apple>() {
    @Override
    public Apple get(a) {
        return newApple(); }};// constructor reference
Supplier<Apple> supplier = Apple::new;
Copy the code

By comparison, we can also see the graceful expression of lambda expressions combined with references, which simplifies the code while enhancing the readability of the code.

Work with functional interfaces

With lambda features come in fact, there are many functional interfaces, if you want to play lambda more smoothly, it is recommended to understand:

  • Predicate —-> provides the test method to determine whether the requirements are met
  • Consumer —-> provides the Accept method to receive objects and consume them
  • Supplier —–> provides the get method for production
  • Function —–> provides the apply methoddiy
// Predicate ----> Provides the test method to determine whether the requirements are met
private static void predicate(a) {
    Predicate<String> predicate = (s) -> s.length() > 5;
    System.out.println(predicate.test("holdonbei"));
}

// Consumer ----> Provides the accept method, which accepts objects and consumes them
private static void consumer(a) {
    Consumer<String> c1 = System.out::println;
    c1.accept("Holdonbei");
}

// Supplier -----> provides the get method for production
private static void supplier(a) {
    Supplier<String> supplier = () -> "holdonbei";
    System.out.println(supplier.get());
}

// Function -----> provide the apply method, return parameters, can be 'diy'
private static void function(a) {
    Function<String, Integer> f = String::length;
}
Copy the code

In addition to these four interfaces, the JDK also provides additional interfaces, interested partners can learn by themselves

Type inference

In a functional interface, our input parameters can be determined in advance. For example:

Comparator<Integer> comparator = (n1, n2) -> n1 - n2;
Copy the code

Since Integer is already indicated in Angle brackets, we can leave the type blank in lambda expressions and Java will do the type derivation for us automatically.

That’s all for today

Stay hungry. Stay foolish. This is Taiyicoding. See you next time