01-lambda

1. lambda

interface IFactory {
    Object getUser();
}

// 接口实现类
class Factory implements IFactory {

    @Override
    public Object getUser() {
        return new User();
    }
}

@Data
@NoArgsConstructor
@AllArgsConstructor
class User {
    private String name;
    private int age;
}
/*
 * Lambda表达式初体验
 *  代码更简洁
 *  函数式编程:更关注函数/功能,而非对象
 *      函数是“第一等公民”
 *      1. 可以赋值给变量
 *      2. 可以作为(其它函数的)参数进行传递
 *      3. 可以作为(其它函数的)返回值
 */
public class T1_Lambda {

    /**
     * 1. 子类实现接口
     */
    @Test
    public void T1_subClass() {
        IFactory factory = new Factory();
        User user = (User) factory.getUser();
        System.out.println(user);
    }


    /**
     * 2. 匿名内部类
     */
    @Test
    public void T2_anonymousClass() {
        // shortcut:new IFactory() => opt + Enter
        IFactory factory = new IFactory() {
            @Override
            public Object getUser() {
                return new User("张三", 39);
            }
        };
        User user = (User) factory.getUser();
        System.out.println(user);
    }

    /**
     * 3. 赋值给变量
     * 只关注函数体(入参列表、返回值)
     */
    @Test
    public void T3_variable() {
        IFactory factory = () -> {
            return new User("李四", 18);
        };
        User user = (User) factory.getUser();
        System.out.println(user);


        // 补充:函数体中,只有简单的表达式语句时,可以省略大括号{}
        factory = () -> new User("王五", 20);
        user = (User) factory.getUser();
        System.out.println(user);
    }

    /**
     * 4. lambda作为实参
     */
    @Test
    public void T5_param() {
        User user = _param(
                () -> new User("赵六", 18),
                "User"
        );
        System.out.println(user);
    }

    public static User _param(IFactory factory, String beanName) {
        Object obj = factory.getUser();
        // obj.getClass().getSimpleName() 获取简单类名
        // obj.getClass().getName() 获取包内路径名
        if (obj != null && obj.getClass().getSimpleName().equals(beanName)) {
            return (User) obj;
        }
        return null;
    }

    /**
     * 5. lambda作为返回值
     */
    @Test
    public void T6_return() {
        IFactory factory = _return();
        System.out.println(factory.getUser());
    }

    private static IFactory _return() {
        return () -> new User("钱七", 18);
    }
}
















 
 










 
 
 
 
 
 










 
 
 





 










 

























 


2. LambdaSyntax

Syntax 英 [ˈsɪntæks] 语法;新泰;句法;句法学;語法

braces 英 [ˈbreɪsɪz] n. 箍子;夹子;支架;(儿童)牙箍;吊裤带;背带

parenthesis 英 [pəˈrenθəsɪs] n. 插入语

brackets 英 [ˈbrækɪts] n. 括号; v. 用括弧括上;

/*
 * 语法:
 *      (parameters) -> { statements; }
 *      (parameters) -> expression
 *  -> :使用指定参数去完成某个功能
 *
 * 前提:必须有一个函数式接口 —— @FunctionalInterface
 * Lambda表达式与@FunctionalInterface的抽象函数格式一一对应
 *
 * @FunctionalInterface
 * 1. 有且只有一个抽象方法的接口
 */
public class T2_LambdaSyntax {

    /**
     * 1. 有且只有一个抽象方法的接口
     * 2. 可以有static()
     * 3. 可以有default()
     */
    @FunctionalInterface
    interface IGreeting {

        void sayHello(String message);

        static void show() {
        }

        default void get() {
        }
    }

    @FunctionalInterface
    interface IMathOper {
        int operation(int a, int b);
    }

    /**
     * 0. 基本格式
     */
    @Test
    public void T1_base() {
        IMathOper add = (int a, int b) -> {
            return a + b;
        };
        System.out.println(add.operation(1, 2));
    }

    /*
     * 1. 省略大括号{}
     */
    @Test
    public void T2_simplify_braces() {
        IGreeting greeting = (String msg) -> System.out.println("hello " + msg);
        greeting.sayHello("Lambda");
    }

    /*
     * 2. 只有一个参数省略小括号()
     */
    @Test
    public void T3_simplify_parenthesis() {
        IGreeting greeting = msg -> System.out.println("hello " + msg);
        greeting.sayHello("ooxx");
    }

    /**
     * 3. 省略return
     */
    @Test
    public void T4_simplify_return() {
        IMathOper mo1 = (int a, int b) -> a + b;
        System.out.println(mo1.operation(3, 4));
    }

    /**
     * 4. 省略参数类型
     */
    @Test
    public void T5_simplify_paramType() {
        IMathOper mo2 = (a, b) -> a * b;
        System.out.println(mo2.operation(6, 5));
    }

}









































 
 
 








 








 








 








 




3. FunctionalInterface

supplier 英 [səˈplaɪə(r)] n. 供应商;供货商;供应者;供货方

negate 英 [nɪˈɡeɪt] vt. 取消;使无效;否定;否认

predicate 英 /ˈpredɪkət , ˈpredɪkeɪt/ v. 使基于;断言;表明;使以…为依据

/**
 * 函数式接口
 */
public class T3_FunctionalInterface {

    /*
     * thread_create
     *      1. Runnable无返回值
     *      2. Callable有返回值
     */
    @Test
    public void T1_runnable() {
        // 1. 匿名内部类方式
        new Thread(new Runnable() {
            @Override
            public void run() {
                String name = Thread.currentThread().getName();
                System.out.println(name + " 线程已启动");
            }
        }).start();

        // 2. Lambda表达式
        new Thread(() -> {
            String name = Thread.currentThread().getName();
            System.out.println(name + " 线程已启动");
        }).start();

        // 3. 简化Lambda
        new Thread(() ->
                System.out.println(Thread.currentThread().getName() + " 线程已启动")
        ).start();
    }

    /*
     * T get();
     */
    @Test
    public void T2_supplier() {
        int[] arr = {2, 3, 4, 52, 333, 23};
        int maxNum = _supplier(() -> {
            // 查找数组的最大值
            return ArrayUtil.max(arr);
        });
        System.out.println(maxNum);
    }

    public static int _supplier(Supplier<Integer> sup) {
        return sup.get();
    }

    /*
     * void accept(T t);
     */
    @Test
    public void T3_consumer() {
        _consumer(System.out::println);

        _consumer(
                s -> System.out.println(s.toLowerCase()),
                s -> System.out.println(s.toUpperCase())
        );
    }

    static void _consumer(Consumer<String> function) {
        function.accept("Hello");
    }

    // Consumer.andThen()
    static void _consumer(Consumer<String> one, Consumer<String> two) {
        one.andThen(two).accept("Hello");
    }

    /*
     * int compare(T o1, T o2);
     */
    @Test
    public void T4_comparator() {
        String[] strs = {"xyz", "abc", "de", "fghi"};
        // 匿名内部类
        Comparator<String> comparator = new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.length() - o2.length();
            }
        };
        Arrays.sort(strs, comparator);
        System.out.println(Arrays.toString(strs));

        // Lambda表达式
        Arrays.sort(
                strs,
                (s1, s2) -> s2.length() - s1.length()
        );
        System.out.println(Arrays.toString(strs));
    }

    /*
     * boolean test(T t);
     *
     * predicate判断、断言
     * & | !
     */
    @Test
    public void T5_predicate() {
        _predicate_and(s -> s.contains("H"), s -> s.contains("W"));

        _predicate_or(s -> s.contains("H"), s -> s.contains("W"));

        _predicate_negate(s -> s.length() < 5);
    }

    /**
     * 与
     */
    static void _predicate_and(Predicate<String> one, Predicate<String> two) {
        boolean isValid = one.and(two).test("Hello world");
        System.out.println("同时包含 H、W:" + isValid);
    }

    /**
     * 或
     */
    static void _predicate_or(Predicate<String> one, Predicate<String> two) {
        boolean isValid = one.or(two).test("Hello world");
        System.out.println("包含 H、w 一个:" + isValid);
    }

    /*
     * boolean test(T t);
     */
    static void _predicate_negate(Predicate<String> predicate) {
        boolean veryLong = predicate.negate().test("Hello world");
        System.out.println("长度不小于5:" + veryLong);
    }

    /*
     * R apply(T t);
     *
     * 输入、输出
     */
    @Test
    public void T6_function() {
        String str = "10";
        _function(
                str,
                p -> Integer.parseInt(p) + 10,
                i -> i *= 10
        );

        str = "郑十,10";
        int age = _function(
                str,
                s -> s.split(",")[1],
                Integer::parseInt,
                n -> n += 18
        );

        System.out.println("郑十年龄为:" + age);
    }

    static void _function(String str, Function<String, Integer> one, Function<Integer, Integer> two) {
        int num = one.andThen(two).apply(str);
        System.out.println(num + 20);
    }

    static int _function(String str, Function<String, String> one, Function<String, Integer> two, Function<Integer, Integer> three) {
        return one.andThen(two).andThen(three).apply(str);
    }

}







 
 

























 
















 





















 























 

















 







 







 




 
























 




 



4. Principle

principle 英 [ˈprɪnsəpl] n. 道德原则;行为准则;规范;法则;原则;原理;观念;(行动、思想的)理由,信条;定律

/*
 * lambda本质:函数式接口的匿名实现类的匿名对象(ASM技术,动态写字节码)
 * lambda表达式是个语法糖
 *
 * JVM参数:jdk.internal.lambda.dumpProxyClasses
 *      命令:java -Djdk.internal.lambda.dumpProxyClasses ClassName
 *      转储得到内部类:ClassName$$Lambda$1.class
 *      反编译:java -jar cfr-0.145.jar LambdaTest.class --decodelambdas false
 *
 * jdk7后支持java动态语言
 */
public class T4_Principle {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("li", "song", "tao");

        list.forEach(System.out::println);
    }
}
/*
public class LambdaPrinciple {
    public static void main(String[] args) {
        List<String> strList = Arrays.asList("\u9a6c", "\u58eb", "\u5175");
        strList.forEach(
            (Consumer<String>)LambdaMetafactory.metafactory(
                    null, null, null,
                    (Ljava/lang/Object;)V,
                    lambda$main$0(java.lang.String ),
                    (Ljava/lang/String;)V
        )());
    }

    private static void lambda$main$0(String s) {
        System.out.println(s);
    }
}

 转储生成的内部类

final class LambdaPrinciple$$Lambda$1 implements Consumer {
    private LambdaPrinciple$$Lambda$1() {
    }

    @LambdaForm.Hidden
    public void accept(Object object) {
        LambdaPrinciple.lambda$main$0((String)object);
    }
}
*/
































 





 





 



5. MethodRef

public class T5_MethodRef {

    @FunctionalInterface
    public interface Printable {
        void print(String s);
    }

    public static void printString(Printable p) {
        p.print("HelloWorld");
    }

    /*
     * 分析:
     *    为什么需要方法引用?
     *    Lambda所要完成的业务逻辑已经存在,已经有某个函数实现了
     *    可以直接引用对应的方法(函数),即方法引用
     *
     *    方法引用语法:
     *        对象名::方法名
     */
    @Test
    public void T1_methodRef() {
        printString(s -> {
            System.out.println(s);
        });

        // 简化
        printString(System.out::println);
    }
}

/*
public class Demo01Printable {
    public static void printString(Printable p) {
        p.print("HelloWorld");
    }

    public static void main(String[] args) {
        Demo01Printable.printString((Printable)LambdaMetafactory.metafactory(
            null, null, null,
            (Ljava/lang/String;)V,
            lambda$main$0(java.lang.String ),
            (Ljava/lang/String;)V)()
        );

        PrintStream printStream = System.out;
        Objects.requireNonNull(printStream);
        Demo01Printable.printString((Printable)LambdaMetafactory.metafactory(
            null, null, null,
            (Ljava/lang/String;)V,
            println(java.lang.String ),
            (Ljava/lang/String;)V)((PrintStream)printStream)
        );
    }

    private static void lambda$main$0(String s) {
        System.out.println(s);
    }
}

转储得到:java -Djdk.internal.lambda.dumpProxyClasses com.mashibing.lambda.demo05.Demo01Printable
    Demo01Printable$$Lambda$1.class
    Demo01Printable$$Lambda$2.class

反编译之后:java -jar cfr-0.145.jar Demo01Printable$$Lambda$1.class --decodelambdas false

final class Demo01Printable$$Lambda$1 implements Printable {
    private Demo01Printable$$Lambda$1() {
    }

    @LambdaForm.Hidden
    @Override
    public void print(String string) {
        Demo01Printable.lambda$main$0(string);
    }
}

final class Demo01Printable$$Lambda$2 implements Printable {
    private final PrintStream arg$1; // 即System.out

    private Demo01Printable$$Lambda$2(PrintStream printStream) {
        this.arg$1 = printStream;
    }

    private static Printable get$Lambda(PrintStream printStream) {
        return new Demo01Printable$$Lambda$2(printStream);
    }

    @LambdaForm.Hidden
    @Override
    public void print(String string) {
        this.arg$1.println(string);
    }
}
*/

6. MethodRefSyntax

/*
 * 类方法 / 构造方法 / 实例方法
 * 条件:被引用方法与函数式接口抽象方法
 * 1. 参数列表相同
 * 2. 返回值类型兼容
 *      void兼容所有返回值类型
 */
public class T6_MethodRefSyntax {

// ---------------------------------------------- 静态方法 ----------------------------------------------

    @FunctionalInterface
    interface Calcable {
        int calsAbs(int number);
    }

    public static int _static_method(int number, Calcable c) {
        return c.calsAbs(number);
    }

    /**
     * 只关注入参、返回值即可
     */
    @Test
    public void T1_static_Method() {
        int num = _static_method(-10, n -> {
            return Math.abs(n);
        });
        System.out.println("num = " + num);

        // 简化
        int num1 = _static_method(-20, Math::abs);
        System.out.println("num1 = " + num1);
    }

// ---------------------------------------------- 构造方法 ----------------------------------------------

    @Data
    @AllArgsConstructor
    static class Person {
        private String name;
    }

    @FunctionalInterface
    interface PersonBuilder {
        Person buildPerson(String name);
    }

    public static void _constructor_method(String name, PersonBuilder pb) {
        Person person = pb.buildPerson(name);
        System.out.println(person.getName());
    }

    @Test
    public void T2_Constructor_Method() {
        _constructor_method("迪丽热巴", name -> new Person(name));

        // 简化
        _constructor_method("古力娜扎", Person::new);
    }

// ---------------------------------------------- 实例方法 ----------------------------------------------

    @FunctionalInterface
    public interface Printable {
        void print(String s);
    }

    public static void _obj_method(Printable p) {
        p.print("Hello");
    }

    static class ObjMethod {

        public void upperCaseStr(String str) {
            System.out.println(str.toUpperCase());
        }
    }

    @Test
    public void T3_Obj_Method() {
        ObjMethod obj = new ObjMethod();
        _obj_method(s -> {
            obj.upperCaseStr(s);
        });

        // 简化
        _obj_method(obj::upperCaseStr);
    }

// ---------------------------------------------- super方法 ----------------------------------------------

    @FunctionalInterface
    public interface Greetable {
        void greet();
    }

    public static void _super_method(Greetable g) {
        g.greet();
    }

    // 父类
    static class Human {

        public void sayHello() {
            System.out.println("Hello 我是Human!");
        }
    }

    // 子类
    static class Man extends Human {

        @Override
        public void sayHello() {
            System.out.println("Hello 我是Man!");
        }

        @Test
        public void T4_Super_Method() {
            _super_method(() -> {
                Human h = new Human();
                h.sayHello();
            });

            // 简化
            _super_method(() -> {
                super.sayHello();
            });

            // 简化
            _super_method(super::sayHello);
        }
    }

// ---------------------------------------------- this方法 ----------------------------------------------

    @FunctionalInterface
    public interface Richable {
        void buy();
    }

    public static void _this_method(Richable r) {
        r.buy();
    }

    static class Husband {

        public void buyHouse() {
            System.out.println("北京二环内买一套四合院!");
        }

        // 相当于一个方法
        @Test
        public void T5_This_Method() {
            _this_method(() -> {
                this.buyHouse();
            });

            // 简化
            _this_method(this::buyHouse);
        }
    }

// ---------------------------------------------- array方法 ----------------------------------------------

    @FunctionalInterface
    public interface ArrayBuilder {
        int[] buildArray(int length);
    }

    public static int[] _array_method(int length, ArrayBuilder ab) {
        return ab.buildArray(length);
    }

    @Test
    public void T6_Array_Method() {
        int[] arr1 = _array_method(10, len -> {
            return new int[len];
        });

        // class [I
        // [:代表数组
        // I:代表int
        System.out.println(arr1.getClass());
        System.out.println(Arrays.toString(arr1));

        // 简化
        int[] arr2 = _array_method(10, int[]::new);
        System.out.println(Arrays.toString(arr2));
    }

}