简述
Java 8由Oracle从2014年3月18日发布,此版本是自Java 5(发布于2004年)之后的一个重量级版本,也是java发展史上的一个里程碑式的版本。这个版本在JVM、编译器、库、Java语法特性等方面都做了很大改进,同时在语言的表达力、简洁性等个方面也有了很大的提高。目前几乎所有的JAVA框架也都已升级到支持JDK8,打开框架源码想了解其设计,假如不理解JDK8的这些特性看起来就会非常吃力。所以我们设计了这个专题,我们将在这个专题中讲解JDK8中的部分关键特性,并用实际案例讲解这些特性应用,希望同学们在JDK8技术的应用上有一个很好的提高。
新特性介绍
Java 8这个版本提供了很多实用的新特性,针对接口推出了接口默认方法,接口静态方法以及函数式接口,同时为了简化代码编写,推出了lambda表达式,为了增强对数据的操作,还定义了Stream操作等。这个版本目前是市场上一个应用最广泛,也是最重要的一个版本。
JDK8中Lambda 表达式应用
在lambda 表达式应用过程中,你应该也注意到了,一般只有两个元素:
(参数类型 参数名) -> {代码体;}
其中“->” 将参数列表与函数主体分离,旨在对给定参数进行处理。函数的主体可能是一条或多条语句。例如其常见结构如下
() -> 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, e2 ) -> e1.compareTo( e2 ) );
Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> {
int result = e1.compareTo( e2 );
return result;
} );
JDK8中Stream API应用
概述
Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作,或者大批量数据操作。
应用场景
在当今这个数据爆炸的时代,数据来源多样化、数据海量化,很多时候不得不脱离 RDBMS,以底层返回的数据为基础进行更上层的数据统计。而原有 Java 的集合 API 中,仅仅有极少量的辅助型方法,更多的时候是程序员需要用 Iterator 来遍历集合,然后完成相关的聚合应用逻辑。这是一种远不够高效而且相对比较笨拙的方法。在JDK8中使用 Stream 对象,不仅丰富了在业务层面对数据处理的方式,还可以让代码更加简洁、易读和高效。
快速入门分析
我们在使用Stream对象时,一般会按照如下为三个步骤进行操作:
第一步:创建Stream流对象。
第二步:Stream流中间操作。
第三步:Stream流终止操作。
Steam对象简易应用,代码如下:
List<Integer> list = Arrays.asList(3, 2, 12, 5, 6, 11, 13);
long count = list.stream()
.filter(i -> i % 2 == 0)
.count();
System.out.println(count);
应用案例增强分析
Stream对象创建。
Stream对象的创建,常见方式有如下几种:
借助Collection接口中的stream()或parallelStream()方法。
借助Arrays类中的stream(…)方法。
借助Stream类中的of(…)方法。
借助Stream类中的iterator和generator方法(无限操作)。
Stream对象创建,案例分析如下:
Collection<Integer> col=new ArrayList<>();
...
Stream<Integer> s1=col.stream();
Stream<Integer> s2=col.parallelStream();
IntStream s3=Arrays.stream(new int[] {1,2,3,4});
Stream<Integer> s4=Stream.of(10,20,30,40);
Stream<Integer> s5=Stream.iterate(2, (x)->x+2);
s5.forEach(System.out::println);
Stream<Double> s6=Stream.generate(()->Math.random());
s6.forEach(System.out::println);
Stream中间操作
Stream 对象创建以后可以基于业务执行一些中间操作,但这些操作的结果需要借助终止操作进行输出,案例分析如下:
初始条件:给定list集合作为Stream操作的对象,代码如下:
List<Integer> list=Arrays.asList(100,101,102,200);
对数据进行过滤:
//输出集合中所有的偶数
//1.创建流
Stream<Integer> s1=list.stream();
//2.中间操作(过滤)
Stream<Integer> s2=s1.filter((n)->n%2==0);
//3.终止操作
s2.forEach(System.out::println);
//也可以将多个操作合在一起
list.stream().filter(n->n%2==0).forEach(System.out::println);
限定操作(limit):
list.stream()
.filter(n->n%2==0)
.limit(2)
.forEach(System.out::println);
跳过操作(skip):
list.stream()
.filter(n->n%2==0)
.skip(2)
.forEach(System.out::println);
去重操作(distinct):
list.stream()
.distinct()
.forEach(System.out::println);
排序操作(sorted):底层基于内部比较器Comparable或外部Comparator比较器进行比对。
list.stream()
.sorted()
.forEach(System.out::println);
list.stream()
.sorted((s1,s2)->{//Comparator
return s1-s2;
}).forEach(System.out::println);
映射操作(map):
List<String> list=Arrays.asList("a","bc","def");
list.stream()
.map((x)->x.toUpperCase())
.forEach(System.out::println);
list.stream()
.map((x)->x.length())
.forEach(System.out::println);
Stream终止操作。
Stream终止操作是Stream的结束操作,案例分析如下:
List<String> list=Arrays.asList("a","bc","def");
list.stream()
.map((x)->x.toUpperCase())
.forEach(System.out::println);
list.stream()
.map((x)->x.length())
.forEach(System.out::println);
案例:初始条件定义,给定一个list集合:
List<Integer> list=Arrays.asList(10,11,12,13,14,15);
match操作:
boolean flag=list.stream().allMatch((x)->x%2==0);
System.out.println(flag);
flag=list.stream().anyMatch((x)->x%2==0);
System.out.println(flag);
flag=list.stream().noneMatch((x)->x>20);
System.out.println(flag);
find操作:
Optional<Integer> optional=list.stream().sorted().findFirst();
System.out.println(optional.get());
optional=list.parallelStream().filter((x)->x%2!=0).findAny();
System.out.println(optional.get());
count操作:
long count=list.stream().count();
System.out.println(count);
求最大,最小值:
optional=list.stream().max((x,y)->{return x-y;});
System.out.println(optional.get());
optional=list.stream().min((x,y)->{return x-y;});
System.out.println(optional.get());
forEach迭代操作:
list.stream().forEach(System.out::println);