常用Java8新特性简单介绍

Lambda匿名函数表达式

  • 最主要的特点:可以将函数作为参数传入方法
  • 实际上,Lambda表达式主要用于实现接口(只有一个待实现方法的接口),比如Runnable接口,内部只有run()方法待实现,那么就可以用Lambda表达式实现Runnable接口:
    Runnable run = () -> System.out.println("run")
    Thread t = new Thread(() ->System.out.println("run"))
    的方式来实现Thread,而不是古老的显式Override的方式。

  • Lambda可以利用编译器做很多自动推理的工作,例如传参、返回值、类型等信息都可以通过编译器自动推理得出,所以在编写的时候可以省略很多东西。例如:

List<Integer> list = new ArrayList<>(Arrays.asList(4, 2, 6, 1));

list.sort(((a, b) -> a - b));

上例中,实际是用(a, b) -> a - b实现了Comparator接口,编译器自动推理出了a和b的类型,以及实现接口的类型,以及省略了return

方法引用

方法引用,可以理解为Lambda的一种简化版,用法是class::method或object::method,方法引用可以分为4类

  • 引用静态方法,ClassName::staticMethod,例如:String::valueOf,对应的Lambda就是(s) -> String.valueOf(s)
  • 引用对象实例的方法,object::method,例如:”a”.toString,对应的Lambda就是 () -> this.toString()
  • 引用特定类型的任意对象的方法,Class::method,例如:String::toString,对应的Lambda就是 (s) -> s.toString
  • 引用构造函数,Class::new,例如:String::new,对应的Lambda是() -> new String()
方法引用示例

假设有个接口:

private static interface Inter {

    String test(String a); 
    //引用对象实例的方法时,去掉String 

}

静态方法引用:Inter inter = String::valueOf; 等效于:inter inter = (a) -> String.valueOf(a);

引用特定类型的任意对象方法:inter inter = String::toString; 等效:inter inter = (a) -> a.toString;

引用对象实例的方法:inter inter = “test”::toString; 等效:inter inter = () -> “test”.toString;

引用构造方法:inter inter = String::new; 等效:inter inter = (a) -> new String(a);

个人认为,先理解了Lambda,再用Lambda来理解方法引用,会更加容易理解

函数式接口

根据上述描述可知,Lambda表达式以及方法引用,实际上都是为了实现接口的,而能被实现的接口都有一个共同点,就是只有一个待实现方法。在Java8中,这种接口被统一称为函数式接口。

在Java8之前,其实就存在了很多这样的接口,比如Runnable、Comparator、InvocationHandler等,在JDK1.8中还加入了java.util.function包,内含有大量的函数式接口可供使用,而Java已经给JDK中所有的函数式接口都加上了@FunctionalInterface接口,来标注这是一个函数式接口

默认方法

Java8中,为每个接口提供了一种可以实现默认方法的机制,定义方法时,在前面加上default就可以了,之后实现这个接口的类都会继承这个默认方法(除非重写了此方法)

另外,还提供了一种静态默认方法,即每个接口都可以实现一个静态方法,之后就可以像类一样,通过接口名直接调用该方法。

例如:

public interface Inter {
    String test(String a);

    default void test2() {
        System.out.println("Default");
    }

    static void test3() {
        System.out.println("Static");
    }
}

Stream

流是一种新的对象,是Java8的新特性之一

对流的操作可以简化为产生流对象->对流进行操作->收集流对象的流程

产生流对象

可以通过Stream的静态方法、Collection的stream()、parallelStream()方法、Arrays.stream(数组)等方式产生一个流对象

对流进行操作
  • filter:设置过滤条件,会返回流,如:stream.filter(a -> a % 2 == 0)
  • forEach: 迭代流中的每个元素进行操作,如:stream.forEach(System.out::println)
  • map:对每一个元素做映射,会返回一个流,如:stream.map(i -> i + 1)
  • limit:截取流的一部分,返回流对象,如:stream.limit(2)
  • sort:对流进行排序,返回流对象,可以带入Comparator自定义排序方式,如:stream.sorted((a, b) -> b-a).forEach(System.out::println),这是将流逆序排序后输出
  • 等等等….
重新收集流对象

收集是为了将流转换回正常POJO对象

  • count:顾名思义,即返回流中对象的数量
  • collect:特别重要,多数流对象是由集合转换来的,所以最后多数也要转换回集合类型,即可以用collect将流中的对象收集并转换为集合。如:stream.collect(Collectors.toList)、stream.collect(Collectors.toSet)、stream.collect(Collectors.toMap(i -> i, i -> i * i))……,在Collectors类中有很多静态方式可供使用

示例:

public static void main(String[] args) {
    Stream<Integer> stream = Stream.of(3, 4, 1, 9, 6, 2, 8, 7, 0); // 生成流对象

    // 逆序排序后截取前5个并返回列表
    List<Integer> list = stream.sorted((a, b) -> b - a).limit(5).collect(Collectors.toList());

    // 过滤出所有奇数,并以自己为key,平方为value存入map中
    Map<Integer, Integer> map = stream.filter((x) -> x % 2 == 1).collect(Collectors.toMap((i) -> i, (i) -> i * i));

    // 返回流中对象的个数
    Long count = stream.count();
    }

Optional

Java8引入了Optional类主要是为了解决null

Optional对象的生成:

    // 不能放入null
    Optional<String> optional = Optional.of("optional");
    // 可以放入null
    optional = Optional.ofNullable(null);
    // 只能是null
    optional = Optional.empty;

Optional对象的操作:

    optional.get(); // 如果非null则返回对象,如果是null则抛出NoSuchElementException异常
    optional.isPresent(); //如果非null返回true,是null则返回false
    // 下面两句的效果是一样的
    optional.ifPresent(System.out::println); 
    if(optional.isPresent()) {
        System.out.println(optional.get());
    }

    optional.orElse(""); //如果为null则返回传入的对象,否则返回内部的对象

    optional.orElseGet(String::new); //如果为null则返回supplier.get, supplier则为传入的接口

    optional.orElseThrow(exceptionSupplier); //如果为null则抛出exceptionSupplier.get,这是一个异常生成的接口

    optional = optional.map((s) -> s + "!"); //如果不为null,则对内部的对象做一个映射并返回Optional对象,如果为null则返回空Optional对象

    optional = optional.flatMap((s) -> Optional.of(s + "!")); //和map不同的一点是,flatMap传入的接口必须返回Optional对象,而map会自动封装

    optional = optional.filter((s) -> s.length() > 6);// 有点像Stream的filter函数,但是不同的是,Stream中包含了大量元素,因此多数时候会有剩下的,但是Optional的filter更像是断言,true则原样返回,false则返回空Optional对象

其他特性

Nashorn, JavaScript 引擎
新的日期API,不需要使用Date+Calendar对日期操作
Java8内置了Base64的编码器和解码器

不再一一赘述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值