2021-09-20 Lambda expression

lambda expressions

@FunctionalInterface

Annotation of functional interface

There can only be one abstract method in a functional interface, not only one method.

1. Basic use

2. Reference method

Method owner: method name

The owner of a static method is a class, and the owner of a common method is an object

package com.chen.lambda;

/**
 * lambda Expression reference method
 */
public class Test {
    public static void main(String[] args) {
        //Reference static methods in this class
        ReturnOneParam returnOneParam = Test::doubleNum;
        int result = returnOneParam.method(20);
        System.out.println(result);

        //Reference non static methods in this class
        Test test = new Test();
        ReturnOneParam returnOneParam1 = test::addTwo;
        int result1 = returnOneParam1.method(10);
        System.out.println(result1);

        //Reference static methods not in this class
        ReturnOneParam returnOneParam3 = Test1::treble;
        int result3 = returnOneParam3.method(20);
        System.out.println(result3);

        //Reference non static methods in this class
        Test1 test1 = new Test1();
        ReturnOneParam returnOneParam2 = test1::addThree;
        int result2 = returnOneParam2.method(10);
        System.out.println(result2);
    }

    /**
     * lambda Requirements for using reference methods in the method body of expressions:
     *
     * Referenced methods and abstract methods in functional interfaces
     * 1,The return value type is consistent
     * 2,The parameter type and number are consistent
     */
    public static int doubleNum(int a){
        return 2*a;
    }

    public int addTwo(int a){
        return a+2;
    }
}

/**
 * A functional interface with a return value and a parameter
 */
interface ReturnOneParam{
    int method(int a);
}

3. Create thread

package com.chen.lambda;

/**
 * lambda The expression implements the run() method of the Runnable interface
 */
public class Test2 {
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName()+" start");
        new Thread(()->{
            for (int i = 0; i < 20; i++) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"\t"+i);
            }
        },"lambda thread").start();
        System.out.println(Thread.currentThread().getName()+" end");
    }
}

4. Operation set

1. Traversal set

package com.chen.lambda;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class Test3 {
    public static void main(String[] args) {
        List<String> list = new ArrayList();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");

        ConsumerImp c = new ConsumerImp();
        /**
         * default void forEach(Consumer<? super T> action) {
         *         Objects.requireNonNull(action);
         *         for (T t : this) {
         *             action.accept(t);
         *         }
         *     }
         */
        list.forEach(c);
    }
}

/**
 * Consumer Is a functional interface
 */
class ConsumerImp implements Consumer{
    @Override
    public void accept(Object o) {
        System.out.println(o);
    }
}

Principle of simplification

  1. Consumer is a functional interface whose abstract method is accept (T)
  2. Each element traversed by the forEach() method is passed to the accept (T) method to perform an operation
  3. If we only need to output this element, that is, system. Out. Println (T)
  4. Both accept (T) and println (T) methods have no return value, only one parameter, and the parameter types are the same (here)
  5. So we refer to the println (T) method as the implementation of accept (T)
  6. The println (T) method is not a static method and needs to be called by an object of the PrintStream class
  7. out is just a static property of PrintStream class, so it is used to represent the owner of println (T) method, PrintStream class

[question] out is an attribute of PrintStream class, not an object! The static attribute is subordinate to the class. You can find the class through the static attribute? So you understand?

package com.chen.lambda;

import java.util.ArrayList;
import java.util.List;

public class Test3 {
    public static void main(String[] args) {
        List<String> list = new ArrayList();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        
        //The simplified version does not even need to pass the printed content
        list.forEach(System.out::println);
    }
}

2. Delete element

package com.chen.lambda;

import java.util.ArrayList;
import java.util.List;

public class Test4 {
    public static void main(String[] args) {
        List<String> list = new ArrayList();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");

        list.removeIf((ele)->{
            return ele.equals("b");
        });
        //simplify
        list.removeIf(ele->ele.equals("b"));
        list.forEach(System.out::println);
    }
}

principle

  1. Abstract method Boolean test (T) of functional interface Predicate

  2. Pass in a parameter and return a Boolean value

  3. realization:

    Incoming element -- each element iterated by the iterator

    Returns a Boolean value -- the equals() method, comparing each element of the iteration with the target element

/**
* Primitive writing
*/
list.removeIf((ele)->{
	return ele.equals("b");
});

/**
* Simplified writing
*/
list.removeIf(ele->ele.equals("b"));

3. Element sorting

package com.chen.lambda;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * 1,Method of passing in comparator
 * 2,Through lambda expression
 */
public class Test5 {
    public static void main(String[] args) {
        List<String> list = new ArrayList();
        list.add("b");
        list.add("c");
        list.add("a");
        list.add("d");

        //list.sort(new MyComparator());
        list.sort((o1,o2)->o1.compareTo(o2));
        list.forEach(System.out::println);

    }
}

class MyComparator implements Comparator<String>{
    @Override
    public int compare(String o1, String o2) {
        return o1.compareTo(o2);
    }
}

5. Closure problem

The essence of a closure is a code fragment, which can also be understood as a reference to a code fragment. In java, anonymous inner classes are also an implementation of closures.

When accessing external variables in closures, the external variables must be final modified, and the virtual machine will automatically add the final keyword for us.

package com.chen.lambda;

public class Test6 {
    public static void main(String[] args) {
        final int n = 10;
        A a = ()->System.out.println(n);;
        a.method();
        //n++;
    }
}

/**
 * Define a functional interface with no return value and no parameters
 */
interface A{
    void method();
}

Tags: Java Lambda

Posted on Mon, 20 Sep 2021 19:56:50 -0400 by Stille