04lambda expression learning notes

Posted by KILOGRAM on Sat, 25 Dec 2021 12:08:52 +0100

               lambda Expression learning notes

1 lambda syntax

Printer.java

package com.tangguanlin.lambda;
public interface Printer {
    void printer(String val);
}

LambdaDemo.java

package com.tangguanlin.lambda;
/**
 * Author: Tang Guanlin
 * Completion date: May 4, 2021
 */
public class LambdaDemo {

    public void printSomething(String something, Printer printer){
        printer.printer(something);
    }
}

LambdaDemoTest.java

package com.tangguanlin.lambda;
/**
 * Implementation without lamdba expression
 * Author: Tang Guanlin
 * Completion date: May 4, 2021
 */
public class LambdaDemoTest {
    public static void main(String[] args) {
        LambdaDemo lambdaDemo = new LambdaDemo();
        String something  ="tewssss";

        //Interface implemented in traditional way
        Printer printer = new Printer() {
            @Override
            public void printer(String val) {
                System.out.println(val);
            }
        };

        //Interface simplification 0 using lamdba expression
        Printer printer0 = (String val)->{
            System.out.println(val);
        };

        //Interface simplification with lamdba expression 1
        Printer printer1 = (val)->{
            System.out.println(val);
        };

        //Interface simplification with lamdba expression 2
        Printer printer2 = (val)->System.out.println(val);

        //Interface simplification with lamdba expression 3
        Printer printer3 = val->System.out.println(val);

        //Interface simplification with lamdba expression 4
        lambdaDemo.printSomething(something,val->System.out.println(val));

        lambdaDemo.printSomething(something,printer1);
    }
}

2 list to map list filtering

Person.java

package com.tangguanlin.lambda;
/**
 * Author: Tang Guanlin
 * Completion date: May 4, 2021
 */
public class Person {
    private String name;
    private int age;

    public Person() {
    }

    public String getName() {
        return name;
    }

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

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

    public int getAge() {
        return age;
    }

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

ListToMap.java

package com.tangguanlin.lambda;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
 * list Transfer to map list filtering
 * Author: Tang Guanlin
 * Completion date: May 4, 2021
 */
public class ListToMap {
    public static void main(String[] args) {

        List<Person> personList = new ArrayList<Person>();
            personList.add(new Person("zhangsan",11));
            personList.add(new Person("lisi",12));
            personList.add(new Person("wangwu",13));
            personList.add(new Person("zhaoliu",15));
            personList.add(new Person("lidamazi",15));
            //list to map age:name
            Map<Integer,String> personMap = personList.stream().collect(Collectors.toMap(Person::getAge,Person::getName,(k1,k2)->k2));
            //list to map age:person
            Map<Integer,Person> personMap2 = personList.stream().collect(Collectors.toMap(Person::getAge, Function.identity(),(k1, k2)->k2));

            //Filter the list
            List<Person> selectedList = personList.stream().filter((Person person)->person.getAge()<15).collect(Collectors.toList());

            //Filter the list and then turn to map
            Map<Integer,Person> personMap3 = personList.stream().filter((Person person)->person.getAge()<15).collect(Collectors.toMap(Person::getAge, Function.identity(),(k1, k2)->k2));
    }
}

3 stream

Employee.java

package com.tangguanlin.lambda;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
 * Author: Tang Guanlin
 * Completion date: May 4, 2021
 */
@AllArgsConstructor
@Data
public class Employee {

    private int id;
    private int age;
    private String gender;
    private String firstName;
    private String lastName;
}

StreamFilterPredicate.java

package com.tangguanlin.lambda;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/** 
 * stream flow
 * Author: Tang Guanlin
 * Completion date: May 4, 2021
 */
public class StreamFilterPredicate {
    public static void main(String[] args) {
        
        List<String> playerList = Arrays.asList("kobe","james","curry","cyyt");

        //Arrays, sets, and files can all be converted to pipeline flows
       List<String> playerSortedList = playerList.stream()  //list to pipe flow
                                                 .filter(s->s.startsWith("c")) //filter
                                                 .map(String::toUpperCase)    //Capitalize
                                                 .sorted()      //sort
                                                 .collect(Collectors.toList());  //Transfer to list
        //The final result can be converted to list, map and set
       System.out.println(playerSortedList);
        
        Employee e1 = new Employee(1,23,"M","Rick","Beethovan");
        Employee e2 = new Employee(2,13,"M","Rick","Hengis");
        Employee e3 = new Employee(3,43,"M","Ricky","Martin");
        Employee e4 = new Employee(4,26,"M","Jon","Lowman");
        Employee e5 = new Employee(5,49,"F","Cristine","Maria");
        Employee e6 = new Employee(6,15,"M","David","eezor");
        Employee e7 = new Employee(7,68,"F","Melissa","Roy");
        Employee e8 = new Employee(8,79,"M","Alex","Gussin");
        Employee e9 = new Employee(9,15,"F","Neetu","Singh");
        Employee e10 = new Employee(10,45,"M","Nayeen","Jain");

        List<Employee> employees = Arrays.asList(e1,e2,e3,e4,e5,e6,e7,e8,e9,e10);

        //Arrays, sets, and files can all be converted to pipeline flows

        //1.filter usage
       List<Employee> employees1 = employees.stream()
                 .filter(e->e.getAge()>70&&e.getGender().equals("M"))
                 .collect(Collectors.toList());
           //The final result can be converted to list, map and set

       //2.map usage: process each element
        List<Employee> employees2=employees.stream()
                .map(e->{
                    e.setAge(e.getAge()+1);
                    e.setGender(e.getGender().equals("M")?"male":"female");
                    return e;
                })
                .collect(Collectors.toList());

        //3. Usage of map + foreach: process each element and output each element
        employees.stream()
                .map(e->{
                    e.setAge(e.getAge()+1);
                    e.setGender(e.getGender().equals("M")?"male":"female");
                    return e;
                })
                .forEach(e->System.out.println(e.getFirstName()));

        //4.limit go to the first few
        List<Employee> employees3=employees.stream()
                                           .limit(2) //Take the first 2
                                            .collect(Collectors.toList());

        //5.skip skip the first few
        List<Employee> employees4=employees.stream()
                                           .skip(2) //Skip the first 2
                                           .collect(Collectors.toList());

        //6.distinct weight removal
        List<Employee> employees5 =employees.stream()
                                            .distinct()
                                            .collect(Collectors.toList());
        //7.sorted
        List<Employee> employees6 = employees.stream()
                                             .sorted(Comparator.comparing(Employee::getAge))
                                             .collect(Collectors.toList());


        //8.sort sort by age
        employees.sort(Comparator.comparing(Employee::getGender) //Gender reverse order
                                 .thenComparingInt(Employee::getAge) //Reverse order of age
                                 .reversed() //Reverse order
                       );

        //9. Whether anymatch exists (even if there is one)
       boolean isHave =  employees.stream().anyMatch(e->e.getAge()>10);

        //10.allMatch are all people older than 18
        boolean isHave2 = employees.stream().allMatch(e->e.getAge()>18);

        //11. None of the nonmetch is less than 18 years old
        boolean isHave3 = employees.stream().noneMatch(e->e.getAge()<18);

        //12. Find elements
       Optional<Employee> OptionalEmployee = employees.stream()
                                                      .filter(e->e.getAge()>10)
                                                      .findFirst();
       Employee employee7 = OptionalEmployee.get();
    }
}

4 lambda application scenario

Lambda expression is a new feature introduced by Java 8. Combined with forEach method, traversal can be realized more conveniently.

In addition, it can also replace the Runnable class, which greatly simplifies the writing of code.

The following describes some common application scenarios in which the timely use of Lambda expressions is more concise and convenient than the usual way.

4.1 list iteration

Operate on each element of a list without Lambda expression as follows:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
for (int element : numbers) {
    System.out.prinln(element);
}

Use Lambda expressions:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.forEach(x -> System.out.println(x));

If you only need to call a single function to process the list elements,

Then you can use a more concise method reference instead of Lambda expression:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.forEach(System.out::println);

4.2 event monitoring

Do not use Lambda expressions

button.addActionListener(new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent e) {
        //handle the event
    }
});

When using Lambda expressions, you need to write multiple statements, which are surrounded by curly braces:

button.addActionListener(e -> {
    
});

4.3 predict interface

java. util. The predict interface in the function package can be easily used for filtering. If you need to filter multiple objects and execute the same processing logic, you can encapsulate these same operations into the filter method, and the caller provides the filter conditions for reuse.

Without the Predicate interface, you need to write filter conditions and processing logic for each object

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<String> words = Arrays.asList("a", "ab", "abc");

numbers.forEach(x -> {
    if (x % 2 == 0) {
        //process logic
    }
})
words.forEach(x -> {
    if (x.length() > 1) {
        //process logic
    }
})

Use the predict interface to encapsulate the same processing logic into the filter method, and call repeatedly:

public static void main(String[] args) {
    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    List<String> words = Arrays.asList("a", "ab", "abc");

    filter(numbers, x -> (int)x % 2 == 0);
    filter(words, x -> ((String)x).length() > 1);
}

public static void filter(List list, Predicate condition) {
    list.forEach(x -> {
        if (condition.test(x)) {
            //process logic
        }
    })
}

The filter method can also be written as:

public static void filter(List list, Predicate condition) {
    list.stream().filter(x -> condition.test(x)).forEach(x -> {
        //process logic
    })
}

4.4 Map mapping

Use the map method of the Stream object to map the original List to another List via a Lambda expression, and convert it back to the List type through the collect method:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> mapped = numbers.stream().map(x -> x * 2).collect(Collectors.toList());
mapped.forEach(System.out::println);

4.5 Reduce aggregation

The reduce operation is to aggregate all elements through binary operation, and finally get a result. For example, using addition to aggregate a list is to accumulate all the elements in the list to get the sum.

Therefore, we can provide reduce with a Lambda expression that receives two parameters, which is equivalent to a binary operation:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream().reduce((x, y) -> x + y).get();
System.out.println(sum);

Replace Runnable

Taking creating a thread as an example, the code of using Runnable class is as follows:

Runnable r = new Runnable() {
    @Override
    public void run() {
        //to do something
    }
};
Thread t = new Thread(r);
t.start();

Use Lambda expressions:

Runnable r = () -> {
    //to do something
};
Thread t = new Thread(r);
t.start();

Or use a more compact form:

Thread t = new Thread(() -> {
    //to do something
});
t.start;

t();
System.out.println(sum);

replace Runnable

Taking creating a thread as an example, use Runnable Class code is as follows:

```java
Runnable r = new Runnable() {
    @Override
    public void run() {
        //to do something
    }
};
Thread t = new Thread(r);
t.start();

Use Lambda expressions:

Runnable r = () -> {
    //to do something
};
Thread t = new Thread(r);
t.start();

Or use a more compact form:

Thread t = new Thread(() -> {
    //to do something
});
t.start;

Topics: Java