JDK1.8的新特性

Lambda表达式

Lambda是1.8中新加的语法糖(不是内部类,匿名类的语法糖),Lambda表达式逻辑上可以理解成实现一个匿名类,这个类只定义了一个方法。
Lambda有两个好处:
1.编码简洁;
2.配合1.8中的新编程方式:函数式接口(FunctionalInterface);
Lambda表达式的格式:(parameters) -> expression,Comparable实现代码示例:

public class Book {

    private int pages;

    public Book(int pages){
        this.pages = pages;
    }

    private Comparable<Book> comparable = (x) ->{
        return Integer.compare(this.pages,x.pages);
    };

    public static boolean isLarge(Book a){
        if(a.getPages() > 1000)
            return true;
        else
            return false;
    }

    public int compareTo(Book a){
        return comparable.compareTo(a);
    }

    public int compareToSum(Book a,Book b){
        return comparable.compareTo(a);
    }

    public int getPages() {
        return pages;
    }

    public void setPages(int pages) {
        this.pages = pages;
    }
}

函数式接口

在上文中我们提到了这个函数式接口的概念,在JDK1.8中对这种只定义唯一一个抽象方法的接口叫做函数式接口,可以用@FunctionalInterface注解来描述,不过这个注解是非必须的。下面是常用的四个核心接口:
在这里插入图片描述
Lamdba表达式就是对这种函数式接口的便捷编程方式。

函数引用(方法引用)

它和Lambda一样都是返回一个函数式接口的实例化对象,可以理解成对一个非函数式接口的某一个函数(方法)实现函数式接口的拆分实例化。换句话说是对函数式接口的另一种支持,是Lambda表达式的一种精简。具体语法如下:

普通函数引用:

1.实例::方法

		Book a = new Book(10000);
        //以下两种定义是等价的
        Function<Book,Integer> f1 = a::compareTo;
        Function<Book,Integer> f2 = (x)-> a.compareTo(x);

2.类::静态方法

        //以下两种定义是等价的
        Predicate<Book> p1 = Book::isLarge;
        Predicate<Book> p2 = x -> Book.isLarge(x);

3.类::方法

		//以下两种定义是等价的
        Function<Book, Integer> pg1 = Book::getPages;
        Function<Book, Integer> pg2 = x -> x.getPages();
构造函数引用

1.普通对象,类::new

		//以下两种定义是等价的
        Function<Integer,Book> c1 = Book::new;
        Function<Integer,Book> c2 = x -> new Book(x);

2.数组,Type[]::new

		//以下两种定义是等价的
        Function<Integer,Book[]> bc1= Book[]::new;
        Function<Integer,Book[]> bc2= x -> new Book[x];

Stream API

Stream就是流,前面是函数式编程的引入,这里的Stream就是对函数式编程的一个应用了,如果我们看Stream这个接口就会发现,里面的入参基本都是函数式接口。看过这个接口定义的方法之后就知道,这个接口的作用是简化Collection(集合)的操作。

常用的方法:

1.构造Stream:
Collection和Arrays都增加了生成Stream的方法.stream();
Stream提供了自己的静态方法.of(),.iterate()和.generate(),其中后两个生成的是无限流。
2.对Stream进行操作,生成另一个Stream:
操作包括filter,limit,skip,distinct,map,sorted。其中map并不是生成map而是根据传入的规则对原始Stream中每个元素进行操作,得到新的Stream。
3.不生成Stream:
主要是查找和匹配。这里说两个特殊操作:reduce返回一个Optional(这个也是1.8新加入的成员,下面会有具体描述)对象,逻辑是对Stream中的元素两两操作,最终返回一个值。这个参数有一定规则。附上代码大家感受一下。代码示例如下:

		String[] strings = new String[]{"123","224","167"};
        Stream<String> s = Arrays.stream(strings);
        Optional<String> ss = s.map(x -> x.substring(0,1)).reduce(String::concat);
        //或者
        //Optional<String> ss = s.map(x -> x.substring(0,1)).reduce((x,y) -> x.concat(y));

注意,注释中的入参只能是两个。第二个操作是collect,返回一个Collection对象,等于对Stream数据的归集生成集合List<String> ss = s.map(x -> x.substring(0,1)).collect(Collectors.toList());
注意:Stream只能操作一次,不能重复操作,需要对一个Stream进行多次操作的话需要生成多个Stream对象。

并行和串行

Stream api中声明可以通过parallel()与sequential()方法在并行流和串行流之间进行切换。 这两个方法和上面提到的方法不同,不会让当前操作的Stream失效。其中并行流的实现使用了fork/join框架。fork拆分,join汇总,采用 “工作窃取”模式(work-stealing这个模式以后具体讲解),下面是fork/join框架的两个核心接口:RecursiveAction(无返回值) 和RecursiveTask(有返回值)。

Optional容器

就个人而言Optional的引入作用并不是很大(纯属个人感觉),首先并没有避免NPE,其次也没有使代码简化(还是要判断),最后还会浪费一些性能。主要作用就是强迫开发人员检验。

接口中可以定义默认方法和静态方法了

在接口中可以使用default和static关键字来修饰接口中定义的普通方法,例子可以看上文中提到的函数式接口中定义的方法。这是一种新的规范,default主要因为原有接口修改,为了上下兼容增加的默认实现,static使得可以直接用接口引用静态方法了。

LocalDate | LocalTime | LocalDateTime

这三个日期都是不可变的,适用于多线程环境。其他和普通的类相似,在此不再做过多的赘述。

总结

JDK1.8主要是主要升级点在于函数式接口的引入(Lambda表达式,方法引用),以及函数式编程的实践(Stream API)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值