zoukankan      html  css  js  c++  java
  • java都13了, 8的新特性你还没不会用吗

    前言

    java13都已经来了,很多同学还停留在使用java5的东西。如果在日常开发中没有使用上java8的一些新特性或者不会用。这篇文章对你可能有帮助。

    lambda表达式

    介绍

    lambda表达式是java8出的一种新的语法,通过匿名调用的方式使代码更加优雅。

    函数式接口

    介绍

    为了更友好的支持lambda表达式,在java8引入了函数式接口的概念。

    • “函数式接口”是指仅仅只包含一个抽象方法,但是可以有多个非抽象方法(默认方法 default 修饰)的接口。
    • “函数式接口”可以使用@FunctionalInterface注解在接口上进行声明 。所以你看到的接口上有这个注解的都是函数式接口。

    在函数式接口中使用lambda表达式

    先看下面一段代码

        @Test
        public void FunctionalInterface(){
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    print();
                }
            });
    
            new Thread(
                () ->{print();}
            );
    
            new Thread(() -> print());
    
            new Thread(this::print);
        }
    
        public void print(){
            System.out.println("hello domain");
        }
    复制代码

    上面的Runnable接口就是一个函数式接口, 第一种创建接口实例的方式使传统的匿名内部类。其余三种方式是使用lambda创建的接口实例。第一种没啥好说的,对其余三种的语法说明下。

    1. 第一种的语法格式是普通的完整的lambda语法,格式是: () -> {},小括号里面的就是接口方法的传参,大括号里面的就是方法里面的逻辑。可以对照匿名实现接口的方式来看。
    2. 第二种方式,对比第一种少了大括号, 当大括号里面的代码是一句代码时,可以省略大括号。
    3. 第三种方式叫做lambda方法引用, 小括号,大括号都没了,只剩下方法引用。 为啥可以这么做, 因为大括号里面的调用的方法入参和小括号里面的入参是一致的。在例子中,小括号和大括号里调用的方法都没有参数,如是有参数会是这样的:
        @Test
        public void testFunctionalInterface(){
            WebService webService = this::print;
            webService.sayHi("domain");
        }
    
        public void print(String str){
            System.out.println("hi:"+str);
        }
    复制代码

    上面例子可以看到两个点, 第一个就是上面说的有参数的lambda实践,第二个是lambda表达式返回的确实是一个接口的实现实例。

    方法引用

    方法引用有三种方式,类名::方法对象::方法类名::new,最后这个语法是引用的构造方法。

    Stream

    介绍

    stream 是java8对集合(不包括map)新增的一个api,配合lambda,更好的对集合进行各种操作。

    使用

    先创建一个list集合,使用stream来对它操作。

        List<User> users = new ArrayList<>();
        users.add(new User("domain",18));
        users.add(new User("alex",19));
        users.add(new User("lily",20));
        users.add(new User("joy",21));
    复制代码

    过滤(filter)

    对集合中的数据进行过滤, 使用filter方法,比如我要拿到集合中年龄大于18的人:

            List<User> users = users.stream()
                    .filter(new Predicate<User>() {
                        @Override
                        public boolean test(User user) {
                            return user.getAge() > 18;
                        }
                    }).collect(Collectors.toList());
    复制代码

    可以看到,匿名内部实现的那一块,可以用lambda表达式来实现:

            List<User> users = users.stream()
                    .filter(user -> user.getAge() > 18).collect(Collectors.toList());
    
    复制代码

    说明:user.stream来获得steam对象,filter进行过滤,collect来生成过滤后的对象,因为原对象不会改变。

    类型转换(map)

    把集合类型和元素改变, 如果我要拿到集合中所有的姓名集合:

            users.stream()
                    .filter((user) -> user.getAge() > 18)
                    .map(User::getName)
                    .forEach(System.out::println);
    复制代码

    这样就是输出所有的姓名。map之后可以通过刚刚的collect转为一个新的集合对象。例子中没有这样做,是通过forEach将每个元素输出出来。

    匹配(match)

    寻找集合中的元素,进行匹配。

    • 任一匹配

    现在我要知道集合中是否存在domain这个名字的人

           boolean anyMatch = users.stream().anyMatch(user -> "domain".equals(user.getName()));
    复制代码
    • 所有匹配

    集合中的名字是否都叫domain

    boolean allMatch = users.stream().allMatch(user -> "domain".equals(user.getName()));
    复制代码
    • 都不匹配

    集合中是否没有domain姓名的人

    boolean noneMatch = users.stream().noneMatch(user -> "domain".equals(user.getName()));
    复制代码

    Optional

    Optional是Java8提供的为了解决null安全问题的一个API,讲通俗点就是对数据的判空检查。来看下面的例子

    • 我想要获取user对象中的一个值,像下面这样:
    user = userService.getUser();
    if (user == null) {
     throw new Excepiton("用户不存在");
    }
    
    复制代码

    可以看到为了对数据的判空, 代码变得非常冗长。Optional 提供了一套API 能使得这种判空检查变得优雅些。

    • orElseThrow
    User user = Optional.ofNullable(userService.getUser()).orElseThrow(() -> new Exception("用户为空为空"));
    
    复制代码

    上面通过调用orElseThrowuser为空时,抛出对应异常。Optional.ofNullable是指定要操作的对象。

    • orElseGet
            String name = Optional.ofNullable(user.getPerson().getName()).orElseGet(() -> "domain");
    
    复制代码

    使用orElseGet来设置对象为空时,返回的默认值。


    作者:domain
    链接:https://juejin.im/post/5db6dbe8e51d452a4366155f


  • 相关阅读:
    《ML in Action》笔记(2) —— ID3决策树
    《ML in Action》笔记(1) —— kNN分类器
    MYSQL笔记
    Javascript代码摘录
    初试mysql存储过程&触发器
    百度地图API应用实践(一) —— 栅格图(草稿)
    2020年8月9日, 网吧, 歌单, 极客时间, 龙岩网络图书馆, 正则, WPS, Python
    2020年8月3日, 网吧 ,
    2020年7月13日,想在网吧搞学习,实属想多了
    账号被盗,什么原因呢?是我的操作系统太脆弱,还是博客园存在安全隐患?
  • 原文地址:https://www.cnblogs.com/kkdn/p/11758712.html
Copyright © 2011-2022 走看看