New java features lambda expressions quick start

Posted by chatmaster on Sun, 26 Dec 2021 21:09:51 +0100

order

With the continuous development of Java language, lambda expression, a new feature provided by Java 8, has become a writing method loved by more and more developers. In order to adapt to the changes of the times, we need to learn this writing method well and apply it in normal development. We start with simple examples and go deep into the complex writing method of lambda step by step. First, our task is to create an interface for comparing the size of two int values, add specific implementation methods to it, and then call it. The interface is defined as follows:

interface Comparator{
    int compare(int a,int b);
}

Conventional writing

Writing method 1: create a new class and implement the interface

Create mycomparator Java and implement Comparator interface:

class MyComparator implements Comparator{
    @Override
    public int compare(int a, int b) {
        return a > b ? a : b; //Output maximum value
    }
}

Then call:

public static void main(String[] args) {
    Comparator comparator = new MyComparator();
    
    int res = comparator.compare(1, 10);
    System.out.println(res);
}

Method 2: use anonymous functions

Direct new interface

public static void main(String[] args) {
    //Using anonymous methods
    Comparator comparator = new Comparator() {
        @Override
        public int compare(int a, int b) {
            return a > b ? a : b;
        }
    };
    
    int res = comparator.compare(1, 10);
    System.out.println(res);
}

lambda writing

Different from the above conventional writing method, lambda only focuses on the input of the method and the logic of the specific implementation in the method body, and all the other saved codes can be omitted. Let's take a look at the first writing method first:

Writing method 1: conventional writing method of lambda

Compare the difference with the anonymous function writing method. Is it very concise? lambda only declares the logic in the input method body. The key point is that the input method body is connected with the - > arrow symbol, which is read as go to.

public static void main(String[] args) {
    //Simple lambda writing
    Comparator comparator = (int a,int b) -> {
        return a > b ? a : b;
    };
    
    int res = comparator.compare(1, 10);
    System.out.println(res);
}

You should have a basic impression here. This step is very important. Stop and think about it.

Writing 2: abbreviation of lambda

Careful observation shows that there is still redundant code in method 1. For example, we have declared the type of input parameter once in the previous interface and declared it again when using it. This is obviously redundant. In fact, the above writing can still be more concise. As long as the following points are met, they can be omitted.

  1. When the input parameter type is consistent with the initial definition type, the input parameter type can be omitted.
  2. When there is only one sentence of code in the method body, braces can be omitted.
  3. When there is only one sentence of code in the method body and the return value is required, the return keyword can be omitted.

A simpler expression is as follows:

public static void main(String[] args) {
    //The input parameter type, braces and return keyword are omitted
    Comparator comparator = (a,b) -> a > b ? a : b;
    
    int res = comparator.compare(1, 10);
    System.out.println(res);
}

Midfield question

The interface we defined above has only one abstract method compare(). Some students will have questions. How to write if there are multiple abstract methods? Good question! The lambda writing method is very concise, but it can only be written under certain conditions. A very important point is that only the interface of an abstract method supports the lambda writing method. This interface is called functional interface and can be modified through @ functional interface annotation.

@Functional interface only modifies functional interfaces, that is, interfaces with only one abstract method.

Method reference of lambda

Writing method I

Only one line of code in the Chinese body of lambda expression can be written in the simplest way. Can't I simplify it if I want to write some complex business? In fact, it is not. At this time, we can use the method reference of swimlane lambda to encapsulate more complex businesses into methods, and then call them in lambda. If it is still the above example, we can encapsulate the line of code in the method body into a method:

public static int max(int a,int b){
    //Here you can write some more complex business
    return a > b ? a : b;
}

In this case, the lambda expression can be written as follows:

public static void main(String[] args) {
    //The max function is referenced in the method body
    Comparator comparator = (a,b) -> max(a,b);
    int res = comparator.compare(1, 10);
    System.out.println(res);
}

The above is an ordinary lambda method reference, which simply means encapsulating the code in the method body into a method, and then calling this method. It should be noted that the return value in the max function must be consistent with the abstract method in the interface, otherwise an exception will be reported.

Writing method 2

Although the above method is simple and effective, there is still redundancy, that is, the method parameters are repeated, and the code (a,b) - > max (a,b); There are two times (a,b) in. In actual development, we generally use another way to replace the - > arrow symbol. Please remember the syntax:

Method's subordinate:: method name.

The subordinate can be understood as the object that can call this method. If the method is static modified, the subordinate is the current class; If it is not static, the subordinate belongs to an object. It doesn't matter if you don't understand. It's clear to see a chestnut.

First look at the complete code:

//Define interface
interface Comparator {
    int compare(int a, int b);
}

public class Program {
    public static void main(String[] args) {
        //Use the method reference of lambda to call the max method, and the subordinate is the class
		Comparator comparator = Program::max;
        int res = comparator.compare(1, 10);
        System.out.println(res);
    }
    //static modification method
    public static int max(int a,int b){
        return a > b ? a : b;
    }
}

From the above code, we find that the previous (a,b) - > max (a,b); Written as Program::max;, Because the method Max is modified by the keyword static, the subordinate should be the Program class. It can also be found that the parameters (a,b) are omitted, which is very concise, but it needs to meet two basic conditions:

  1. Parameters can be omitted only if the parameter format of the abstract method in the interface is the same as that of the defined method.
  2. The return value of the abstract method in the interface must be the same as that of the defined method.

This is the new feature introduced by Java 8, all for simplicity and clarity.

How to write a method other than static?

After understanding the above, this is easier to understand. Post the code without explanation

public class Program {
    public static void main(String[] args) {
        //Create a Program object
        Program p = new Program();
        //Use the lambda method reference to call the max method, and the subordinate is the object
		Comparator comparator = p::max;
        int res = comparator.compare(1, 10);
        System.out.println(res);
    }
    //Methods not modified by static
    public int max(int a,int b){
        return a > b ? a : b;
    }
}

Exercises

The materials are as follows:

Person.java

class Person{
    String name ;
    int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

Prepare set

public class Program {
    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(new Person("Zhang San",18));
        list.add(new Person("Li Si",30));
        list.add(new Person("Wang Wu",16));
        list.add(new Person("Zhao Liu",20));
        list.add(new Person("pseudo-ginseng",40));
        list.add(new Person("Ma Ba",25));        
        printList(list);
    }
    
    //Print set
    public static void printList(List<Person> list){
        for (Person person : list) {
            System.out.println(person);
        }
    }
}

1. Sort the collection according to the specified attributes

Sort from low to high according to the age of person

Common sorting method:

//Sort in the normal way
list.sort(new Comparator<Person>() {
    @Override
    public int compare(Person o1, Person o2) {
        return o1.getAge() - o2.getAge();
    }
});

Question: can you change the ordinary sorting method into lambda? Is there any other way to think after writing it?

2. List Transform foreach method into lambda method

Normal list traversal:

list.forEach(new Consumer<Person>() {
    @Override
    public void accept(Person person) {
		System.out.println(person.toString());
    }
});

Question: how to transform it into lambda?? After modification, modify the traversal code in exercise 1

3. Delete the specified element in the collection

Delete people older than 35

Normal deletion:

list.removeIf(new Predicate<Person>() {
    @Override
    public boolean test(Person person) {
        return person.age > 35;
    }
});

Question: how to transform it into lambda??

answer

  1. Sort (one out of two)
list.sort((p1,p2) -> p1.getAge() - p2.getAge());
Collections.sort(list,(p1,p2) -> p1.getAge() - p2.getAge());
  1. ergodic
list.forEach(person -> System.out.println(person.toString()));
  1. Deletes the specified element
list.removeIf(person -> person.age > 35);

reference resources: https://www.bilibili.com/video/BV164411E7Ny?p=1

Topics: Java Lambda interface