Java 8语法糖: Lambda表达式、StreamAPI、Optional

 

Lambda表达式

面向对象编程是对数据的抽象,面向函数编程是对行为的抽象。

Lambad表达式是一个匿名函数,可以说是接口或者抽象类的一种实现。

使用场景:

  • 使用了@Functional 注释的函数式接口

  • 自带一个抽象函数的方法

  • SAM(Single Abstract Method 单个抽象方法)类型

这些称为lambda表达式的目标类型,可以用作返回类型,或lambda目标代码的参数。例如,若一个方法接收Runnable、Comparable或者 Callable 接口,都有单个抽象方法,可以传入lambda表达式。

Lambda表达式使用

lambda表达式的本质: 作为函数式接口的实例

举例: (o1,o2) -> {
					Integer.compare(o1,o2);
				};
格式:
		-> : lambda操作符
		->左边 : lambda形参列表 (其实就是接口中的抽象方法的形参列表)
		->右边 : lambda体  (其实就是重写的抽象方法体)
// 无参数,无返回
    @Test
    public void noArgument() {

        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名接口实现");
            }
        };
        r1.run();

        Runnable r2 = () -> System.out.println("lambda实现");
//        由此看出,lambda表达式的本质就是接口的实例
        r2.run();
    }

匿名接口实现
lambda实现

lambda表达式特征:

  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。

  • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。

  • 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。

  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。

函数式接口

只包含一个抽象方法的接口,称为函数式接口。

可以通过Lambda表达式来创建该接口的对象。

定义: 使用@FunctionalInterface注解

Stream API

Stream 是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。

使用Stream API对集合进行操作,就类似于使用SQL执行的数据库查询。简单来说,Stream API提供了一种高效的处理数据的方式。

Stream是什么

stream是数据渠道,用于操作数据源(集合、数组)等所生成的元素序列。

与Collention的区别 : “集合讲的是数据,Stream讲的是计算“。

Stream执行流程

Stream的实例化

 List<String> list = Arrays.asList("aaa", "bbb", "cccc");
        
//        stream() : 顺序流
        Stream<String> stream = list.stream();

//       parallelStream() : 并行流
        Stream<String> parallelStream = list.parallelStream();

一系列的中间操作

筛选和切片

//      filter(Predicate p)   --- Predicate断言  接收Lambda表达式,从流中排除某些元素
        users.stream().filter(user -> user.getAge()>25).forEach(System.out::println);
        System.out.println();
//        limit(n) 截断流 ----只取n条数据
        users.stream().limit(3).forEach(System.out::println);
        System.out.println();

//        skip(n) 跳过流 ----不要前n条数据
        users.stream().skip(3).forEach(System.out::println);
        System.out.println();

//        skip(n) 跳过流 ----不要前n条数据
        users.stream().skip(3).forEach(System.out::println);
        System.out.println();

//        distinct 去重 ----
        users.stream().distinct().forEach(System.out::println);
        System.out.println();

映射 Stream的map方法可以将集合中的每个对象转化为其他对象。

可以理解为将每个对象都进行处理、转换。

List<Student> list = new ArrayList<>();
        Student stu1 = new Student("张三", 24);
        Student stu2 = new Student("李四", 22);
        Student stu3 = new Student("王五", 25);
        Collections.addAll(list, stu1, stu2, stu3);
        List<Teacher> teacList = list.stream().map(stu -> {
            String name = stu.getName();
            int age = stu.getAge();
            return new Teacher(name, age);
        }).collect(Collectors.toList());
        teacList.stream().forEach(teacher -> System.out.println(teacher));
        //Teacher{name='张三', age=24}
        //Teacher{name='李四', age=22}
        //Teacher{name='王五', age=25}

排序

//        sorted()   ---自然排序
        List<Integer> list = Arrays.asList(23, 12, 455, 32, 4, 20);
        list.stream().sorted().forEach(l -> System.out.println(l));

//        sorted(Comparator com)  ---定制排序
        List<User> users = UserData.getUsers();
        users.stream().sorted((u1,u2) -> {
            int compare = Double.compare(u1.getSalary(), u2.getSalary());
            if (compare !=0) {
                return compare;
            }else {
                return Integer.compare(u1.getId(), u2.getId());
            }
        }).forEach(System.out::println);

终止操作

1-匹配与查找

List<User> users = UserData.getUsers();

        // allMatch(Predicate p) - 检查是否匹配所有元素。  ---是否所有的员工的年龄都大于18
        boolean match = users.stream().allMatch(user -> user.getAge() > 18);
        System.out.println(match);

        // anyMatch(Predicate p) - 检查是否至少匹配一个元素。 ---是否存在员工的工资大于10000
        boolean b = users.stream().allMatch(user -> user.getSalary() > 10000);
        System.out.println(b);

        // noneMatch(Predicate p) - 检查是否没有匹配的元素。(没有返回true,有返回false) --是否存在员工姓"雷"
        boolean noneMatch = users.stream().allMatch(user -> user.getName().startsWith("雷"));
        System.out.println(noneMatch);

        // findFirst - 返回第一个元素
        Optional<User> first = users.stream().findFirst();
        System.out.println(first.get());

        // findAny - 返回当前流中的任意元素
        Optional<User> any = users.stream().findAny();
        System.out.println(any.get());

        // count - 返回流中元素的总个数
        long count = users.stream().filter(user -> user.getSalary() > 5000).count();
        System.out.println(count);

        // max(Comparator c) - 返回流中最大值   ---------返回最高的工资:
        Stream<Double> salaryStream = users.stream().map(e -> e.getSalary());
        Optional<Double> maxSalary = salaryStream.max(Double::compare);
        System.out.println(maxSalary);

        // min(Comparator c) - 返回流中最小值  ---------返回最低工资的员工
        Optional<User> user = users.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
        // Optional[User(id=1005, name=陈几十块, age=30, salary=90.5)]
        System.out.println(user);

        // forEach(Consumer c) - 内部迭代
        users.stream().forEach(System.out::println);

2-归约 reduce 相加

 // reduce(T identity,BinaryOperator) - 可以将流中元素反复结合起来,得到一个值。返回 T
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Integer sum = list.stream().reduce(0, Integer::sum);
        // 55
        System.out.println(sum);

        // reduce(BinaryOperator) - 可以将流中元素反复结合起来,得到一个值。返回 Optional<T>   ----计算公司所有员工工资的总和
        List<User> users = UserData.getUsers();
        Optional<Double> reduce = users.stream().map(user -> user.getSalary()).reduce((s1, s2) -> s1 + s2);
        System.out.println(reduce.get());   // 36893.8

3-收集 collect(Collector c) 将流转换为集合

 List<User> users = UserData.getUsers();

        // collect(Collector c):将流转换为其他形式。接收一个 Collector 接口的实现,用于给 Stream 中元素做汇总的方法
        // ----查找工资大于 6000 的员工,结果返回为一个 List 或者 set
        List<User> userList = users.stream().filter(user -> user.getSalary() > 6000).collect(Collectors.toList());
        userList.forEach(System.out::println);

        Set<User> userSet = users.stream().filter(user -> user.getSalary() > 6000).collect(Collectors.toSet());
        userSet.forEach(System.out::println);

Optional类

这是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。

简单来说,这个类提供了一种判空的方式。

两个主要的方法:

isPresent: 如果值存在返回true,否则返回false。
get: 如果Optional有值则将其返回,否则抛出NoSuchElementException。

 // findFirst - 返回第一个元素
        Optional<User> first = users.stream().findFirst();
        if (!first.isPresent()){
            return;
        }else {
            first.get().setAge(111);
        }
        System.out.println(first.get());

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值