Java8新特性
作者:互联网
Java8 新特性
Java8最重要的两个改变,一个是Lambda表达式,另一个就是Stream API。
Lambda表达式
一段可以传递的代码 -> 更紧凑的代码风格
接口中一定要只有一个抽象方法才可以这么写,成为函数式接口
这也是java8在接口中引入静态和默认方法的原因
本质:作为接口的实例
左边是形参列表,右边是重写的抽象方法的方法体
- 无参,无返回值 () -> 方法体
Runnable r2 = () -> System.out.println("aaa");
r2.run;
-
一个参数,无返回值 (String s) -> {}
-
数据类型可以省略,类型推断 (s) -> {}
-
只有一个参数时,小括号可以省略 s -> {}
-
多个参数,多条执行语句,可以有返回值 (a, b) -> {
System.out.println("aa");
return a - b;
}
- 只有一条语句时,return与大括号若有,都可以省略
函数式接口
函数式接口只可以有一个抽象方法
适配OOF,面向函数编程
在函数式语言中,Lambda表达式的类型是函数,java8中,Lambda表达式是对象,必须依附于函数式接口
方法引用
当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用。
方法引用可以看做是Lambda表达式深层次的表达。(也还是Lambda表达式,也是函数式接口的一个实例)
实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致!
使用::将类(或对象)与方法名分割开来
对象::实例方法名
类::静态方法名
类::实例方法名
int compare(T t1, T t2)
t1.compareTo(t2)
String :: compareTo
第一个参数作为调用者,第二个参数作为输入参数
Stream API
java.util.stream 把函数式编程风格引入Java。
可以对集合执行非常复杂的查找、过滤和映射数据等操作。类似于使用SQL执行数据库查询。
提供了高效且易于使用的处理数据的方式。
为什么用Stream API
- 需要处理NoSQL数据
- Stream和Collection区别:集合是静态的内存数据结构,Stream是关于计算的。前者面向内存,存储在内存中。后者面向CPU,通过CPU实现计算。
什么是Stream
Stream是数据取到,用于操作数据源(集合、数组等)所生成的元素序列。主要讲的是计算。
- Stream不会自己存储元素
- Stream不会改变源对象,他们会返回一个持有结果的新Stream
- 创建Stream,通过数据源获取一个流
- 中间操作链,对数据源的数据进行处理
- 执行终止操作时,执行中间操作链,产生结果。之后不会再被使用
- Stream延迟执行,会等到需要结果的时候才执行。
创建方式
- 通过集合
- default Stream
stream() 返回一个顺序流 - default Stream
parallelStream() 返回一个并行流 - Stream
stream = list.stream();
- default Stream
- 通过数组
- Arrays的静态方法
- static
Stream stream(T[] array) - int[] arr = new int[]{1, 2, 3};
- Stream<int[]> stream = Arrays.stream(arr)
- 通过Stream的of()方法
- Stream
stream = Stream.of(1,2,3,4,5,6);
- Stream
- 创建无限流
- 迭代:Stream.iterate()
- 遍历前10个偶数
- Stream.iterate(0, t -> t + 2).limit(10).forEach(System.out.println);
- 生成:Stream.generate()
- Stream.generate(Math::random).limit(10).forEach(System.out.println);
- 迭代:Stream.iterate()
中间操作
除非遇到终止操作,否则不处理 -> 惰性求值
筛选与切片
方法 | 描述 |
---|---|
filter(Predicate p) | 接收Lambda,从流中排除某些元素。保留为true的 |
distinct() | 筛选,通过元素的hashCode和equals筛选 |
limit(long size) | 截断流,使元素不超过给定数量 |
skip(long n) | 跳过元素,返回一个扔掉了前n元素的流,若元素不足n个,返回空流。 |
映射
方法 | 描述 |
---|---|
map(Function f) | 转换形式或者提取信息 |
flatMap(Function f) | 流中的每一个值都转换为另一个流,并合流。拆分再转换 |
排序
方法 | 描述 |
---|---|
sorted() | 产生一个新流。按自然顺序排序 |
sorted(Comparator com) | 产生一个新流,按传入比较器顺序排序 |
终止操作
匹配与查找
方法 | 描述 |
---|---|
allMatch(Predicate p) | 检查是否匹配所有元素 |
anyMatch(Predicate p) | 检查是否至少匹配一个元素 |
noneMatch(Predicate p) | 检查是否没有匹配所有元素 |
findFirst() | 返回第一个元素 |
findAny() | 返回当前流中的任意元素 |
count() | 返回流中元素总数 |
max(Comparator c) | 返回流中最大值 |
min(Comparator c) | 返回流中最小值 |
forEach(Consumer c) | 内部迭代(使用Collection接口需要用户去做迭代->外部迭代) |
归约
方法 | 描述 |
---|---|
reduce(T iden, BinaryOperator b) | 将流中元素反复结合,得到一个值,返回T |
reduce(BinaryOperator b) | 将流中元素反复结合,得到一个值,返回Optional |
//计算1-10的和
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Integer sum = list.stream().reduce(0, Integer::sum);
System.out.println(sum);
//:计算公司所有员工工资的总和
List<Employee> employees = EmployeeData.getEmployees();
Optional<Double> sumSalary = employees.stream().map(e -> e.getSalary()).reduce(Double::sum);
System.out.println(sumSalary);
收集
方法 | 描述 |
---|---|
collect(Collector c) | 将流转换成其他形式。接收一个Collector接口的实现,给Stream中元素做汇总。 |
//练习1:查找工资大于6000的员工,结果返回为一个List或Set
List<Employee> employees = EmployeeData.getEmployees();
List<Employee> employeeList = employees.stream().filter(e -> e.getSalary() > 6000).collect(Collectors.toList());
employeeList.forEach(System.out::println);
System.out.println();
Set<Employee> employeeSet = employees.stream().filter(e -> e.getSalary() > 6000).collect(Collectors.toSet());
employeeSet.forEach(System.out::println)
Optional类
为了解决java中的空指针问题而生。
Optional
是一个容器类,或者仅仅保存null
Optional.of(T t) 创建一个Optional实例,t必须非空
Optional.empty() 创建一个空的Optional实例
Optional。ofNullable(T t) t可以为null
对反射支持增强
降低了创建对象、对象复制和反射创建对象的时间
参考
标签:stream,Stream,Optional,元素,特性,println,方法,Java8 来源: https://www.cnblogs.com/ogleede/p/16600199.html