Lambda 表达式DEMO 案列

首先新建一个测试Bean 
package com.lambda.bean;

public class Employee {

    private String name;

    private Integer age;

    private float price;

    private Status status;

    public Employee(){
    }
    public Employee(String name, Integer age, float price) {
        this.name = name;
        this.age = age;
        this.price = price;
    }

    public Employee(String name, Integer age, float price, Status status) {
        this.name = name;
        this.age = age;
        this.price = price;
        this.status = status;
    }

    public Employee(float price){
        this.price=price;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    public float getPrice() {
        return price;
    }

    public float getPrice1(float price){
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

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

    public enum Status{
        FREE,
        BUSY,
        VICATION;
    }
}


//新建测试 demo 类
public class Demo1 {

    List<Employee> employees = Arrays.asList(
            new Employee("张三",22,8888.88f, Employee.Status.BUSY),
            new Employee("李四",42,4444.44f, Employee.Status.BUSY),
            new Employee("王五",32,6666.66f, Employee.Status.FREE),
            new Employee("赵六",52,7777.77f, Employee.Status.FREE),
            new Employee("田七",62,3333.33f, Employee.Status.BUSY),
            new Employee("王八",12,9999.99f, Employee.Status.VICATION)
    );

    /**
     * Lambda 表达式基础语法
     */
    @Test
    public void test1() {
        // 对比之前
        Runnable runnable = new Runnable(){
            @Override
            public void run() {
                System.out.println("hello world!");
            }
        };
        runnable.run();

        // Lambda
        // 语法格式一:无参,无返回值
        Runnable r = () -> System.out.println("Hello Lambda!");
        r.run();

        // 语法格式二:有参,无返回值
        Consumer<String> consumer = (e) -> System.out.println(e);
        consumer.accept("Hello Lambda Consumer!");

        //语法格式三:有一个参数,小括号可以不写
        Consumer<String> c = e -> System.out.println(e);
        c.accept("Hello Lambda Consumer!");

        //语法格式四:有两个以上的参数,Lambda 体中有多条语句
        Comparator<Integer> comparator = (x, y) -> {
            System.out.println("排序开始");
            return Integer.compare(x, y);
        };

        //语法格式五:若 Lambda 体中只有一条语句, return 和大括号都可以省略不写
        Comparator<Integer> comparator1 = (Integer x, Integer y) -> Integer.compare(x, y);

        //语法格式六:Lambda 参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出数据类型,即“类型推断”
        Comparator<Integer> comparator2 = (x, y) -> Integer.compare(x, y);

    }

    /**
     * 四大核心函数式接口
     *      Consumer<T>:消费型接口
     * 			void accept(T t);
     *
     * 		Supplier<T>:供给行接口
     * 			T get();
     *
     * 		Function<T,R> : 函数型接口
     * 			R apply(T t);
     *
     * 		Predicate<T> : 断言型接口
     * 			R apply(T t);
     */
    @Test
    public void test2(){
        // Consumer<T>:消费型接口
        Consumer<String> consumer= (e)-> System.out.println("Hello "+e);
        consumer.accept("world!");

        // Supplier<T>:供给行接口
        Supplier<String> supplier = ()->"Hello";
        System.out.println(supplier.get());

        //Function<T,R> : 函数型接口
        Function<Integer,Integer> function = (e)->e*10;
        Integer sum = function.apply(10);
        System.out.println(sum);

        //Predicate<T> : 断言型接口
        Predicate<String> predicate = e->e.equals("hello world");
        System.out.println(predicate.test("hello"));
        System.out.println(predicate.test("hello world"));
    }

    /**
     方法引用:若 Lambda 体中的内容有方法已经实现,我们可以使用“方法引用”
     (可以理解为方法引用是 Lambda 表达式的另外以中表现形式)

     主要有三种语法格式:
     对象::实列方法名
     类::静态方法名
     类::实列方法名
     注意:
     1. Lambda 体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的韩术列表和返回值保持一致!
     2. 若 Lambda 参数列表中的第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以用 ClassName::method

     数组引用:Type[]::new
     */
    @Test
    public void test3(){
        //对象::实列方法名
        Consumer<String> consumer = System.out::println;
        consumer.accept("Hello world");

        Employee employee= new Employee();
        employee.setAge(10);
        Supplier<Integer> supplier=employee::getAge;
        System.out.println(supplier.get());

        Employee employee1= new Employee();
        Function<Float,Float> function=employee1::getPrice1;
        System.out.println(function.apply(10f));

        //类::静态方法名
        Comparator<Integer> comparator= Integer::compare;
        System.out.println(comparator.compare(10,1));

        //类::实列方法名
        BiPredicate<String,String> biPredicate = String::equals;
        System.out.println(biPredicate.test("a","a"));

        //构造器引用
        Supplier<Employee> supplier1= Employee::new;
        System.out.println(supplier1.get());
        Function<Float,Employee> function1=Employee::new;
        System.out.println(function1.apply(11f));

        //数组引用:Type[]::new
        Function<Integer,String[]> f = (e)->new String[e];
        System.out.println(f.apply(10).length);
        Function<Integer,String[]> f1=String[]::new;
        System.out.println(f1.apply(20).length);

    }

    /**
     * 查找与匹配
     * 	allMatch--检查是否匹配所有元素
     * 	anyMath--检查是否至少匹配一个元素
     * 	noneMatch--检查是否没有匹配所有元素
     * 	findFirst--返回第一个元素
     * 	findAny-- 返回当前流中的任意元素
     * 	count--返回流中元素的总个数
     * 	max--返回流中最大值
     * 	min--返回流中最小值
     */
    @Test
    public void test4(){
        boolean b = employees.stream().allMatch((e)->e.getPrice()>3000);
        System.out.println(b);

        boolean b1 = employees.stream().anyMatch((e)->e.getPrice()>5000);
        System.out.println(b1);

        boolean b2 = employees.stream().noneMatch((e)->e.getPrice()>10000);
        System.out.println(b2);

        Optional<Employee> opt = employees.stream().findFirst();
        System.out.println(opt);

        Optional<Employee> opt1 = employees.stream().findAny();
        System.out.println(opt1);

        Long count = employees.stream().count();
        System.out.println(count);

        Optional<Employee> opt3 = employees.stream().max((e1,e2)->Float.compare(e1.getPrice(),e2.getPrice()));
        System.out.println(opt3.get());

        Optional<Float> opt4 = employees.stream().map(Employee::getPrice).min(Float::compareTo);
        System.out.println(opt4.get());
    }

    /**
     * 规约与收集
     *
     * 	规约-- 可以将流中元素结合起来得到一个值。
         * 	reduce(T identity,BinaryOerator)
         * 	reduce(BinaryOperator)
     *
     * 	收集--collect 接收一个 Collector 接口的实现,用于给 Stream 元素汇总的方法
     */
    @Test
    public void test5(){
        // 规约--reduce
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
        Integer sum = list.stream().reduce(0,(x,y)->x+y);
        System.out.println(sum);

        //统计员工工资总和
        Optional<Float> opt = employees.stream().map(Employee::getPrice).reduce(Float::sum);
        System.out.println(opt.get());

        //收集--collect
        employees.stream().map(Employee::getPrice).collect(Collectors.toList()).forEach(System.out::println);
        //平均值
        Double avg = employees.stream().collect(Collectors.averagingDouble(Employee::getPrice));
        System.out.println(avg);
        //总合
        Double sum1 = employees.stream().collect(Collectors.summingDouble(Employee::getPrice));
        System.out.println(sum1);
        //最大值
        Optional opt1 = employees.stream().collect(Collectors.maxBy((e1,e2)->Float.compare(e1.getPrice(),e2.getPrice())));
        System.out.println(opt1.get());
        //最小值
        Optional opt2 = employees.stream().map(Employee::getPrice).collect(Collectors.minBy(Float::compare));
        System.out.println(opt2.get());
        //分组
        Map<Employee.Status,List<Employee>> map = employees.stream().collect(Collectors.groupingBy(Employee::getStatus));
        System.out.println(map);
        //多级分组
        Map<Employee.Status,Map<String,List<Employee>>> map1 = employees.stream().collect(Collectors.groupingBy(Employee::getStatus,Collectors.groupingBy((e)->{
            if(e.getAge()>20){
                return "青年";
            }else if(e.getAge()>30){
                return "中年";
            }else{
                return "老年";
            }
        })));
        System.out.println(map1);
        //分区
        Map<Boolean,List<Employee>> map3 = employees.stream().collect(Collectors.partitioningBy(e->e.getAge()>30));
        System.out.println(map3);
        //Summary 使用
        IntSummaryStatistics summary = employees.stream().collect(Collectors.summarizingInt(Employee::getAge));
        System.out.println(summary.getMax());
        System.out.println(summary.getAverage());
        System.out.println(summary.getCount());
        // join 拼接
        String str = employees.stream().map(Employee::getName).collect(Collectors.joining());
        System.out.println(str);
    }

    /**
     * 并行流-parallel
     */
    // 20亿 888 毫秒左右
    @Test
    public void test6(){
        Instant start = Instant.now();
        Long sum = LongStream.rangeClosed(0L,2000000000L).parallel().reduce(0,Long::sum);
        System.out.println(sum);
        Instant end = Instant.now();
        System.out.println(Duration.between(start,end).toMillis());
    }
    // 对比串行流 20亿 1387 毫秒左右。在往上加到 50 亿,串行流我这里已经跑不动了,但是并行parallel的可以
    @Test
    public void test7(){
        Instant start = Instant.now();
        long sum = 0L;
        for(int i=0;i<=2000000000L;i++){
            sum +=i;
        }
        System.out.println(sum);
        Instant end = Instant.now();
        System.out.println(Duration.between(start,end).toMillis());
    }
}

 

文档说明:

一,Lambda 表达式基础语法:Java8中引入了一个新的操作符 "->" 改操作符称为箭头操作符或 Lambda 操作符
箭头操作符将 Lambda 表达式擦划分成两部分:
    左侧:Lambda 表达式的参数列表
    右侧:Lambda 表达式所需要执行的功能,即 Lambda 体

    语法格式一:无参,无返回值
        () -> System,out.printLn("Hello Lambda!");

    语法格式二:有一个参数,无返回值
        (e) -> System.out.println(e);
    
    语法格式三:有一个参数,小括号可以不写
        e -> System.out.println(e);

    语法格式四:有两个以上的参数,Lambda 体中有多条语句
        Comparator<Integer> comparator = (x,y)->{
                        System.out.println("排序开始");
                        return Integer.compare(x,y);
                };
    
    语法格式五:若 Lambda 体中只有一条语句, return 和大括号都可以省略不写
        Comparator<Integer> comparator1 = (x,y)-> Integer.compare(x,y);

    语法格式六:Lambda 参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出数据类型,即“类型推断”
        (Integer x,Integer y)-> Integer.compare(x,y);    


二,Lambda 表达式需要“函数式接口”的支持
    函数式接口:接口中只有一个抽象方法的接口,称为函数式接口。可以使用 @FunctionalInterface 修饰
        可以检查是否是函数式接口

    java8 中四大核心函数式接口:
        Consumer<T>:消费型接口
            void accept(T t);

        Superlier<T>:供给行接口
            T get();

        Function<T,R> : 函数型接口
            R apply(T t);

        Predicate<T> : 断言型接口
            R apply(T t);


三,方法引用:若 Lambda 体中的内容有方法已经实现,我们可以使用“方法引用”(可以理解为方法引用是 Lambda 表达式的另外以中表现形式)

    主要有三种语法格式:
        对象::实列方法名
        Consumer<String> consumer = System.out::println;
        类::静态方法名
        Comparator<Integer> comparator= Integer::compare;
        类::实列方法名
        BiPredicate<String,String> biPredicate = String::equals;
    注意:    1. Lambda 体重条用方法的参数列表与返回值类型,要与函数式接口中抽象方法的韩术列表和返回值保持一致!
        2. 若 Lambda 参数列表中的第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以用 ClassName::method
    
    数组引用:Type[]::new
        Function<Integer,String[]> f1=String[]::new;

四 Stream
一,Stream 的三个操作步骤:
    1. 创建 Stream 
        集合方式:list.stream()
        数组方式:arrays.stream()
        arrays 静态方法:arrays.steam(arrays)
        Stream 静态方法 of:Stream.of("aa","bb","cc")
        无限流,迭代:Stream.iterate(0,(x)->x+2)
    
    多个中间操作可以链接起来形成一个流水线,
    除非流水线上触发终止操作,否则中间操作不会执行任何的处理!
    而在终止操作时一次性全部处理,称为“惰性求值”。

    2. 中间操作
        list.stream().short,limt(),filter......
    3. 终止操作
        stream.forEach(System.out::println);

二,中间操作
    映射
        map:将元素转换成其他形式或提取信息。 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
        List<String> list = Arrays.asList("aa","bb","cc","dd");
        list.stream().map((str)->str.toUpperCase()).forEeach(System.out::println);
        
        map 返回格式:{{a,a},{b,b},{c,c},{d,d}}    

        flatMap:接收一个函数 作为参数,将流中的每个值链接成一个流
        list.stream().flatMap((str)->str.toUpperCase());
        
        flatMap 返回格式:{a,a,b,b,c,c,d,d}
    
    排序
       shorted()--自然排序
        List<String> list = Arrays.asList("bb","aa","cc","dd");
        list.stream().shorted().forEache(System.out::println);

       shorted(Comparator com)--定制排序    
        List<Employee> employees = Arrays.asList(
                        new Employee("张三",22,8888.88f),
                        new Employee("李四",42,4444.44f),
                        new Employee("王五",32,6666.66f),
                        new Employee("赵六",52,7777.77f),
            );    
        employees.stream()
        .shorted(e1,e2) ->e1.getAge().compareTo(e2.getAge())
        .forEache(System.out::println);

三,查找与匹配
    allMatch--检查是否匹配所有元素
    anyMath--检查是否至少匹配一个元素
    noneMatch--检查是否没有匹配所有元素
    findFirst--返回第一个元素
    findAny-- 返回当前流中的任意元素
    count--返回流中元素的总个数
    max--返回流中最大值
    min--返回流中最小值

四,规约与收集
    规约-- 可以将流中元素结合起来得到一个值。
    reduce(T identity,BinaryOerator)
    reduce(BinaryOperator)

    ------------案列-------------------
    // 规约--reduce
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
           Integer sum = list.stream().reduce(0,(x,y)->x+y);
        System.out.println(sum);

           //统计员工工资总和
        Optional<Float> opt = employees.stream().map(Employee::getPrice).reduce(Float::sum);
        System.out.println(opt.get());

    收集--接收一个 Collector 接口的实现,用于给 Stream 元素汇总的方法
    
    employees.stream().map(Employee::getPrice).collect(Collectors.toList()).forEach(System.out::println);
        //平均值
        Double avg = employees.stream().collect(Collectors.averagingDouble(Employee::getPrice));
        System.out.println(avg);
        //总合
        Double sum1 = employees.stream().collect(Collectors.summingDouble(Employee::getPrice));
        System.out.println(sum1);
        //最大值
        Optional opt1 = employees.stream().collect(Collectors.maxBy((e1,e2)->Float.compare(e1.getPrice(),e2.getPrice())));
        System.out.println(opt1.get());
        //最小值
        Optional opt2 = employees.stream().map(Employee::getPrice).collect(Collectors.minBy(Float::compare));
        System.out.println(opt2.get());
        //分组
        Map<Employee.Status,List<Employee>> map = employees.stream().collect(Collectors.groupingBy(Employee::getStatus));
        System.out.println(map);
        //多级分组
        Map<Employee.Status,Map<String,List<Employee>>> map1 = employees.stream().collect(Collectors.groupingBy(Employee::getStatus,Collectors.groupingBy((e)->{
            if(e.getAge()>20){
                return "青年";
            }else if(e.getAge()>30){
                return "中年";
            }else{
                return "老年";
            }
        })));
        System.out.println(map1);
        //分区
        Map<Boolean,List<Employee>> map3 = employees.stream().collect(Collectors.partitioningBy(e->e.getAge()>30));
        System.out.println(map3);
        //Summary 使用
        IntSummaryStatistics summary = employees.stream().collect(Collectors.summarizingInt(Employee::getAge));
        System.out.println(summary.getMax());
        System.out.println(summary.getAverage());
        System.out.println(summary.getCount());
        // join 拼接
        String str = employees.stream().map(Employee::getName).collect(Collectors.joining());
        System.out.println(str);


五,并行流 - parallel()
    // 20亿 888 毫秒左右
    @Test
    public void test6(){
    Instant start = Instant.now();
    Long sum = LongStream.rangeClosed(0L,2000000000L).parallel().reduce(0,Long::sum);
    System.out.println(sum);
    Instant end = Instant.now();
    System.out.println(Duration.between(start,end).toMillis());
    }
    // 对比串行流 20亿 1387 毫秒左右。在往上加到 50 亿,串行流我这里已经跑不动了,但是并行parallel的可以
    @Test
    public void test7(){
    Instant start = Instant.now();
    long sum = 0L;
    for(int i=0;i<=2000000000L;i++){
        sum +=i;
    }
    System.out.println(sum);
    Instant end = Instant.now();
    System.out.println(Duration.between(start,end).toMillis());
    }
    
六,Optional<T> 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。
常用方法:
    Optional.of(T t); 创建一个 Optional 实例
    Optional.empty(); 创建一个空的 实例
    Optional.ofNullable(T t); 若 t 不为 null ,常见一个 Optional 实例额,否则创建空实例
    isPresent(); 判断是否包含值
    orElse(T t); 如果调用对象包含值,返回该值,否则返回 t
    orElseGet(Supplier s); 如果调用对象包含值,返回值,否则返回 s 获取值
    map(Function f); 如果有值对其处理,并返回处理后的 Optional,否则返回 Optional.empty()
    flatMap(Function mapper); 与 map 类似,要求返回必须是 Optional

    
 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值