转载

java都13了, 8的新特性你还没不会用吗

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

lambda表达式

介绍

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

函数式接口

介绍

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

@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创建的接口实例。第一种没啥好说的,对其余三种的语法说明下。

() -> {}
@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 来设置对象为空时,返回的默认值。

原文  https://juejin.im/post/5db6dbe8e51d452a4366155f
正文到此结束
Loading...