Java8新特性

Oracle 公司于2014年3月18 日发布Java 8,它支持函数式编程,新的JavaScript引擎,新的日期API,新的Stream API等

Lambda 表达式

  • Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中)
  • 格式
1
2
3
4
5
6
7
8
9
(参数1,参数2) -> 单行执行逻辑

(参数1,参数2) ->{
多行执行逻辑;
}
// 当参数为1个时可以省略()
参数 ->{
多行执行逻辑;
}

特征和注意

  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值
  • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号
  • 可选的大括号:如果主体包含了一个语句,就不需要使用大括号
  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值
  • lambda表达式只能引用标记了final的外层局部变量,这就是说不能在lambda内部修改定义在域外的局部变量,否则会编译错误
  • lambda表达式的局部变量可以不用声明为final,但是不可以被后面的代码修改
  • 在lambda表达式当中不允许声明一个与局部变量同名的参数或者局部变量

方法引用

  • 方法引用通过方法的名字来指向一个方法
  • 方法引用使用一对冒号::
  • lambda体中调用方法的参数列表与返回值类型,要与函数式接口中的抽象方法的函数列表和返回值类型保持一致
  • lambda参数列表中的第一参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用类名::方法名
1
2
3
4
5
6
7
8
// 构造器引用
类名::new

// 静态方法引用
类名::静态方法名字

// 打印
System.out::println

函数式接口和默认方法和静态方法

  • 函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口
  • 函数式接口可以被隐式转换为lambda表达式
  • static方法:实现接口的类或者子接口不会继承接口中的静态方法
  • default方法:如果接口中的默认方法不能满足某个实现类需要,那么实现类可以覆盖默认方法
1
2
3
4
5
6
7
8
9
10
11
12
@FunctionalInterface
interface testFInterface {
void t1(String msg);
// 静态方法
static void staticMethod() {
System.out.println("这是一个静态方法");
}
// default方法
default void defaultMethod() {
System.out.println("这是一个default方法");
}
}

Stream API

获取流的方式

  1. 通过Collection系列集合提供的stream()parallelStream()
  2. 通过Arrays中的静态方法stream(),获取数组流
  3. 通过Stream类的静态方法of()
  4. 无限流创建Stream的iterate()方法
1
2
3
4
5
6
7
8
9
10
11
12
13
// 1.
List<String> list = new ArrayList<>();
Stream<String> s1 = list.stream();

// 2.
int[] in = new int[10];
IntStream s2 = Arrays.stream(in);

// 3.
Stream<String> s3 = Stream.of("1", "2");

// 4.
Stream<Integer> s4 = Stream.iterate(0, x -> x + 1);

常用

  • filter:接收lambda,从流中排除某些元素
  • limit:截断流,使元素不超过给定的数量
  • skip(n):跳过元素,返回一个扔掉了前n个元素的流,若流中的元素不足n个,则返回一个空流
  • distinct:筛选,通过流生成元素的hashCode()和equals()去除重复元素
  • map:接收lambda,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并映射为一个新的元素
  • flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
  • reduce将流中的元素反复结合,得到一个值
  • collect(Collector c):将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中元素做汇总
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
List<Integer> list = Arrays.asList(1, 2, 3, 3, 4, 5);
list.stream()
.skip(2)
.limit(2)
.filter(e -> e > 1)
.distinct()
.forEach(System.out::println);
list.stream()
.map(e ->
e + 1
)
.forEach(System.out::println);
Integer reduce = list.stream()
// 从0开始,反复累加
.reduce(0, Integer::sum);
Optional<Integer> reduce1 = list.stream()
.reduce(Integer::sum);

list.stream()
.map(e -> e + 1)
.collect(Collectors.toList())
.forEach(System.out::println);
// 总数
Long count = list.stream()
.collect(Collectors.counting());
// 平均值
Double avg = list.stream()
.collect(Collectors.averagingLong(list::get));
// 总和
Double sum = list.stream()
.collect(Collectors.summingDouble(list::get));
DoubleSummaryStatistics collect = list.stream()
.collect(Collectors.summarizingDouble(list::get));
System.out.println(collect.getMax());
System.out.println(collect.getAverage());
System.out.println(collect.getCount());
System.out.println(collect.getMax());
System.out.println(collect.getMin());
// 分组
Map<Object, List<Integer>> collect = list.stream()
.collect(Collectors.groupingBy(Employee::getStatus));

List<UserInfoEntity> list2 = Arrays.asList(
UserInfoEntity.builder().nickName("1").build(),
UserInfoEntity.builder().nickName("2").build(),
UserInfoEntity.builder().nickName("3").build(),
UserInfoEntity.builder().nickName("4").build(),
UserInfoEntity.builder().nickName("5").build()
);
// 合并字符串
String all = list2.stream()
.map(UserInfoEntity::getNickName)
.collect(Collectors.joining());

// 逗号分隔
String all2 = list2.stream()
.map(UserInfoEntity::getNickName)
.collect(Collectors.joining(","));

long reduce2 = LongStream.rangeClosed(0, 100000000000L)
// 使用并行流进行累加
.parallel()
.reduce(0, Long::sum);

Optional类

  • Optional.of(T t):创建一个Optional实例
  • Optional.empty():创建一个空的Optional实例
  • Optional.ofNullable(T t):若t不为null,创建Optional实例,否则创建空实例
  • isPresent():判断是否包含值
  • orElse(T t):如果调用对象包含值,则返回该值,否则返回t
  • orElseGet(Supplier s):如果调用对象包含值,返回该值,否则返回s获取的值
  • map(Functional f):如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
  • flatMap(Functional mapper):与map类似,要求返回值必须是Optional

相关文章

数据库连接池

SpringIOC

Junit和Spring

Tomcat

Servlet

Request,Response和ServletContext

Cookie和Session

JSP和EL和Jstl

Filter和Listener

Mybatis