Java8新特性详解

2022-11-20 12:38:41

JDK8 新特性

1、简介

详细视频讲解下载

1.1 概述

java 8由Oracle从2014年3月18日发布,此版本是自Java 5(发布于2004年)之后的一个重量级版本,也是java发展史上的一个里程碑式的版本。==这个版本在JVM、编译器、库、Java语法特性等方面都做了很大改进,同时在语言的表达力、简洁性等个方面也有了很大的提高。==目前几乎所有的JAVA框架也都已升级到支持JDK8,打开框架源码想了解其设计,假如不理解JDK8的这些特性看起来就会非常吃力。所以我们设计了这个专题,我们将在这个专题中讲解JDK8中的部分关键特性,并用实际案例讲解这些特性应用,希望同学们在JDK8技术的应用上有一个很好的提高。

1.2 新特性介绍

Java 8这个版本提供了很多实用的新特性,针对接口推出了接口默认方法,接口静态方法以及函数式接口,同时为了简化代码编写,推出了lambda表达式,为了增强对数据的操作,还定义了Stream操作等。这个版本目前是市场上一个应用最广泛,也是最重要的一个版本。

2、接口新特性应用

2.1 概述

JDK8中对接口规范进行了新的定义,允许在接口中定义默认方法(使用default关键字修饰),静态方法,同时还推出了函数式接口(使用@Functionlnterface注解描述)设计。

2.2 应用场景

基于JDK8中接口新规范的定义,不仅可以扩展接口新功能(新的标准),还能保持接口向前兼容的特性。例如Java API中的集合操作规范。

2.3 快速入门分析

default方法设计及实现

JDK8中为了对接口业务进行扩展,但又不影响实现类,提供了默认方法。此类型的方法使用default关键字修饰,可以有方法体的实现。例如

interface IA{defaultvoiddoMethod01(){System.out.println("doMethodo1");}defaultvoiddoMethod02(){System.out.println("doMethodo2");}}

接口默认方法提高了编程的灵活度,一个类在实现接口时,接口中假如有默认方法,默认方法可以有选择性的对其进行重写,但不是必须要重写,例如∶

classClassAimplements IA{}

接口默认方法,解决了java8和以前接口版本特性的兼容性问题,对于我们以后的程序开发,可以在接口子类中直接使用接口默认方法,而并不再需要在各个子类中都去实现这些方法了。

接口中的static方法设计及实现

java8k中的接口规范,不仅允许定义多个默认方法,也有允许在接口中定义多个静态方法,这些静态方法类似于class中的静态方法,可以通过接口名进行直接调用。

inteface IB{staticvoiddoMethod(){Sysout.out.println("doMethod()");}}

接口中静态方法并不能在实现类中被覆写,实现类中可以声明相同的方法,但这两个方法之间除了名字相同,并没有override关系。

函数式接口设计及实现

Java8引入了一个是函数式接口(Functional Internet),此接口使用@FunctionalInterface修饰,并且此接口内部只能包含一个抽象方法。可以写多个default方法。

@FunctionalInterfacepublicinterfaceComparator<T>{intcompare(T o1,T o2);}

说明:函数式接口推出的目的主要是为了配合后续Lambda表达式的应用。

2.4 应用案例增强分析及实现

在JDK8中的java.util.function包中定义了大量函数式接口。常用的有如下几个:

消费型接口

特点:方法有入参,没有返回值。

@FunctionalInterfacepublicinterfaceComparator<T>{voidaccept(T t);...}

函数式接口

特点:方法有入参,有返回值

@FunctionalInterfacepublicinterfaceFunction<T,R>{Raccept(T t);...}

判定式接口

特点:方法有入参,返回值为Boolean

@FunctionalInterfacepublicinterfacePredicate<T>{booleantest(T t);...}

供给式接口

特点:方法没有入参,但有返回值

@FunctionalInterfacepublicinterfaceSupplier<T>{Tget();...}

说明:这些接口可以配合Lambda使用以减少我们自己接口的定义。

3、lambda表达式应用

3.1 概述

Java中的Lambda表达式是JDK8中的一种新特性,它允许我们将一段代码(这段代码可以理解为一个接口的实现)当成参数传递给某个方法,然后进行业务处理,这种方式更像是一种函数式编程风格,可以让代码结构更简洁,开发效率更高。

3.2 应用场景

Java中的Lambda为JAVA编程注入了函数式编程思想,在迭代操作,映射操作,聚合操作等很多方面的实现上做出了很大努力。并从语法角度简化了程序员对特定代码的编写,通过底层的类型推断,方法引用等特性让代码表现的更加优雅。现在已成为我们编程过程中常用的一种编程方式。

3.3 快速入门分析

最简单的Lambda表达式可由逗号分隔的参数列表 ,->符号和语句块组成,例如:

Arrays.asList("a","b","c").forEach(e->System.out.println(e));

在上面这个代码中的参数e的类型是由编译器得出的,你也可以显示指定该参数的类型,例如:

Arrays.asList("a","b","d").forEach((String e)->System.out.println(e));

如果Lambda表达式需要更复杂的语句块,则可以使用花括号将该语句括起来,类似于Java中的函数体,例如:

Arrays.asList("a","b","d").forEach( e->{System.out.println(e);System.out.println("======")});

lambda 表达式可以让代码编写更加简洁。我们先来思考下普通的函数或方法具备的几个元素∶

  • 访问修饰符

  • 返回值类型

  • 方法名

  • 参数列表

  • 代码块

在lambda 表达式应用过程中,你应该也注意到了,一般只有两个元素∶

(parameter list)-> body

其中"->"将参数列表与函数主体分离,旨在对给定参数进行处理。函数的主体可能是一条或多条语句。例如其常见结构如下∶

()-> statement
arg-> statement(arg1,arg2,...)->{ body-block}(Type1 arg1,Type2 arg2,...)->{ method-body-block:return value;}

Lambda表达式有返回值,返回值的类型也由编译器推理得出。如果Lambda表达式中的语句块只有一行,则可以不用使用return语句,下列两个代码片段效果相同∶

Arrays.asList("a","b","d").sort(( e1, e2I)-> e1.compareTo( e2));
Arrays.asList("a","b","d").sort(( e1,e2)->{int result= e1.compareTo( e2);return result;});

3.4 应用案例增强分析及实现

结合对象lambda表达式基本语法的认识,分析如下案例∶

简化线程对象创建

构建一个线程对象,执行Runnable类型的任务,传统方式的实现,其关键代码如下∶

newThread(newRunnable(){@overridepublicvoidrun(){System.out.println("hello");}}).start();

基于JDK8中的Lambda表达式实现方式,对传统方式线程对象的创建进行简化,其关键代码如下∶

newThread(()->{System.out.println("hello");}).start();

简化排序操作的实现团

定义一字符串数组,然后对字符串数组中的内容,按字符串元素的长度对其进行排序。代码如下∶

String[] strArray={"abcd","ab","abc"};

在JDK8之前传统的实现方案,基于Arrays类对数组中的元素进行排序操作,关键代码实现如下∶

Arrays.sort(strArray,newComparator<String>(){@overridepublicintcompare(String o1,String o2){return o1.length()-02.length();}});

基于JDK8中的Lambda表达式,对排序如上排序方案的代码实现过程进行简化,关键代码如下∶

Arrays.sort(strArray,(s1,s2)-> s1.length()-s2.1ength());

4、方法(MethodReference)引用

4.1 概述

方法引用是用来直接引用类方法、实例方法或者构造方法的一种新的方式。这里要特别强调一点的是"方法引用"提供的是一种对方法的引用而不是执行方法的方式,简单点理解的话就是可以将方法作为参数进行传递,我们还可以将方法引用理解为lambda的一种深层表达。

4.2 应用场景

方法引用是一种更简洁易懂的Lambda表达式,操作符是双冒号"::",也可以将方法引用看成是一个更加紧凑,易读的Lambda表达式。

4.3 快速入门分析

定义一个list集合,然后基于Lambda表达式迭代集合中的内容进行输出,关键代码如下∶

List<String> list=Arrays.asList("a","b","c");

list.forEach(str->System.out.println(str));

基于方法引用的方式,输出list集合中的具体内容的,然后与传统Lambda表达式方式,进行对比分析,关键代码如下:

list.forEach(System.out::println);

说明:当你要访问的接口方法与执行的方法引用参数相同,返回值也相同即可直接使用方法引用。

4.4 应用案例增强分析

JDK8方法的引用可分为如下几类:

构造器方法引用

格式: Class::new,引用默认构造函数

importjava.util.function.Supplier;publicclassTestClassIntanceMethond01{publicstaticvoidmain(String[] args){//1.传统方式Supplier<Object> s1=newSupplier<Object>(){@OverridepublicObjectget(){returnnewObject();}};System.out.println(s1.get());//2.Lambda方式Supplier<Object> s2=()->newObject();System.out.println(s2.get());//3.构造方法引用 "类名::new"Supplier<Object> obj=Object::new;System.out.println(obj.get());}}

类静态方法引用

格式:ClassName::static_method

importjava.util.function.Function;classTestClassIntanceMethond02{publicstaticvoidmain(String[] args){//1.传统应用方式Function<String,Integer> f1=newFunction<String,Integer>(){@OverridepublicIntegerapply(String t){returnInteger.parseInt(t);}};Integer result= f1.apply("100");System.out.println(result);//2.lambda应用方式Function<String,Integer> f2=(t)->Integer.parseInt(t);System.out.println(f2.apply("200"));//3.类方法引用应用方式"类名::方法名"Function<String,Integer> f3=Integer::parseInt;System.out.println(f3.apply("300"));}}

练习:比较两个整数大小

Comparator<Integer> com=Integer::compare;System.out.println(com.compare(23,34));

类实例方法引用

格式:ClassName::method,方法不能带参数。

importjava.io.File;importjava.util.function.Function;classTestClassInstanceMethod03{publicstaticvoidmain(String[] args){//1.传统方式Function<File,String> f1=newFunction<File,String>(){@OverridepublicStringapply(File f){return f.getAbsolutePath();}};System.out.println(f1.apply(newFile("pom.xml")));//2.Lambda方式Function<File,String> f2= file-> file.getAbsolutePath();System.out.println(f2.apply(newFile("pom.xml")));//3.类实例方法引用"类名::实例方法名"Function<File,String> f3=File::getAbsolutePath;System.out.println(f3.apply(newFile("pom.xml")));}}

练习:

String[] strArray={"a","dad","ffd"};//LambdaArrays.sort(strArray,(o1, o2)-> o1.compareTo(o2));// 类实例方法Arrays.sort(strArray,String::compareTo);

对象实例::method,方法不能带参数

publicstaticvoidmain(String[] args){List<String> list=Arrays.asList("A","C","D","B");//传统方法
        list.forEach(newConsumer<String>(){@Overridepublicvoidaccept(String s){System.out.println(s);}});//Lambda表达式方式
        list.forEach(t->System.out.println(t));//方法引用方式PrintStream ps=System.out;
        list.forEach(ps::println);
        list.forEach(System.out::println);}

练习:

List<Integer> list=Arrays.asList(10,23,25);Supplier<Integer> supplier= list::size;System.out.println(supplier.get());

5、Stream式操作应用

5.1 概述

Stream 作为 Java 8的一大亮点,它与 java.io 包里的 InputStream和OutputStream 是完全不同的概念。Java8中的 Stream是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作,或者大批量数据操作。

5.2 应用场景

在当今这个数据爆炸的时代,数据来源多样化、数据海量化,很多时候不得不脱离 RDBMS,以底层返回的数据为基础进行更上层的数据统计。而原有 Java 的集合API中,仅仅有极少量的辅助型方法,更多的时候是程序员需要用 lterator 来遍历集合,然后完成相关的聚合应用逻辑。这是一种远不够高效而且相对比较笨拙的方法。在JDK8中使用 Stream 对象,不仅丰富了在业务层面对数据处理的方式,还可以让代码更加简洁、易读和高效。

5.3 快速入门分析

我们在使用Stream对象时,一般会按照如下为三个步骤进行操作∶

  • 第一步∶创建Stream流对象。
  • 第二步∶Stream流中间操作。
  • 第三步∶Stream流终止操作。

Stream对象的操作过程,可通过下面的图进行进一步分析。

Steam对象简易应用,代码如下:

publicstaticvoidmain(String[] args){List<Integer> list=Arrays.asList(3,2,12,4,6,7,22,11,13);long count= list.stream().filter(i-> i%2==0).count();System.out.println(count);}

5.4 应用案例增强分析

Stream对象创建

Stream对象的创建,常见方式有如下几种:

  • 借助Collection接口中的stream()或parallelStream()方法。
  • 借助Arrays类中的stream(…)方法。
  • 借助Stream类中的of(…)方法。
  • 借助Stream类中的iterator和generator方法(无限操作)

Stream对象创建,案例分析如下

importjava.util.Arrays;importjava.util.List;importjava.util.UUID;importjava.util.stream.IntStream;importjava.util.stream.Stream;classTestClassStream01{publicstaticvoidmain(String[] args){List<Integer> list=Arrays.asList(10,32,20,13);//        创建流对象// 方式1//        list.stream( ).forEach(t -> System.out.println(t));//顺序流//        list.stream( ).forEach(System.out :: println);//并行流
        list.parallelStream().forEach(System.out::println)
  • 作者:陶喜儿
  • 原文链接:https://blog.csdn.net/jiabaoyu114/article/details/123785733
    更新时间:2022-11-20 12:38:41