Java 8新特性lambda表达式,未完成。

基本理解

  • lambda表达式的类型依赖于上下文,通过编译器编译阶段javac即可推断出来,程序依旧要经过类型检查保证运行的安全性。
  • lambda表达式可以传入外部既成事实上是final的变量,比如只赋值了一次。
  • 函数接口是只有一个抽象方法的接口,用作lambda表达式的类型
  • Stream 是用函数式编程方式在集合类上进行复杂操作的工具
  • 通常是一系列的惰性求值行成的链,然后通过一个早求值返回想要的结果,与Builder模式有共通之处。
  • 及早求值函数执行之前,惰性函数求值不会真正参与运算。
  • Stream是一个接口,继承了AutoCloseable,一个流只能消费一次(调用及早求值方法一次)。
  • 流可以嵌套使用,流的某个步骤需要某个值也可以通过流来获取。
  • 掌握重要的函数接口,要融会贯通。

基本函数接口:

接口 参数 返回类型 示例
Predicate T boolean 这张唱片已经发行了吗
Consumer T void 输出一个值
Function T R 获得 Artist 对象的名字
Supplier None T 工厂方法
UnaryOperator T T 逻辑非(!)
BinaryOperator (T, T) T 求两个数的乘积(*)

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Predicate<Integer> predicate = x -> x == 1;
Consumer<Integer> consumer = x -> System.out.println(x);
Function<Integer, Integer> function = x -> x = x + 1;
Supplier<Integer> supplier = () -> 1;
UnaryOperator<Integer> unaryOperator = x -> x + 1;
BinaryOperator<Integer> binaryOperator = (x, y) -> x * y;

System.out.println(predicate.test(1));
consumer.accept(1);
System.out.println(function.apply(1));
System.out.println(supplier.get());
System.out.println(unaryOperator.apply(1));
System.out.println(binaryOperator.apply(1, 2));

基本特性

  • 基本类型与包装类型:ToLongFunction, mapToInt
  • @FunctionalInterface注解:强制javac检查一个接口是否符合函数接口的标准,即只有一个抽象方法的接口,如Comparator接口的compare方法则是抽象方法,其他不是。
  • 默认方法(default):增加默认方法的目的是实现接口向后兼容,类中重写的方法优先级高于接口中定义的默认方法
  • 接口多重继承默认方法相同,需要显示指定调用的父接口方法
  • Optional避免NullPointerException,消除if语句
  • 方法引用、元素排序、收集器(转换为其他集合、转换成值、数据分块、数据分组、字符串)、并行处理
  • 方法引用是一种更简短的语法,如artist -> artist.getName()可以简写为Artist::getName,标准语法为Classname::methodName,分为三种:
    • 指向静态方法的引用,如Objects::nonNull
    • 指向任意类型实例方法的引用,如String::length
    • 指向现有对象的实例方法引用,如user::getName
  • 使用并行流时,forEach无法保证元素是按顺序处理,应该使用forEachOrdered。
  • peak可以查看流中的每个值,类似forEach操作但不是及早求值方法

常用场景

常用Java 8 API

collect:将流转换为一个集合。
filter:过滤出流中符合条件的元素。
map:将流中的每个元素转化为另一个元素。
flatMap:将底层元素全部抽出来放到一个流中,将多个流合并为一个流进行操作。
reduce:将Stream流中的数据通过递归的方式,聚合成一个数据,

1
Stream.of(nums1, nums2).flatMap(num -> num.stream()).forEach(System.out::println);

reduce:递归概念,归约成一个值。

1
reduce([p1,p2,p3,p4],fn) = reduce([fn(p2,p4),fn(p1,p3)])

集合的遍历(List, Set, Map)

1
2
3
// 遍历map
map.forEach((key, value) -> System.out.println(key + "=" + value));

##

集合之间的转换

常用方法如下,可以查看源码获取重载方法:
Collectors.toList(), Collectors.toSet(), Collectors.toMap(), Collectors.toConcurrentMap(), Collectors.toArray()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// list转map
Map<String, String> map = channelParameters.stream()
.sorted(Comparator.comparing(ChannelParameter::getVersion).reversed())
.collect(Collectors.toMap(ChannelParameter::getName,
ChannelParameter::getValue, (v1, v2) -> v1));

// 对象数组转Map
Map<String, String> studentMap = Arrays.stream(studentArray).collect(Collectors.toMap(Student::getName, Student::getScore));

// String[]转set
Set<String> set = Arrays.stream(strArray).collect(Collectors.toSet());

// 多线程解密
List<Runnable> jobs = getDecryptJobs(xxx);
CompletableFuture<?>[] futures = jobs.stream()
.map(job -> CompletableFuture.runAsync(job,
AsyncManager.getExecutor("decryptParam", getSupportExecutorProvider())))
.toArray(CompletableFuture[]::new);

排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 写法1
Collections.sort(studentList);
// 写法2, Comparator也可以不采取匿名类的形式
Collections.sort(studentList, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getScore() - o2.getScore();
}
});
// 写法3
Collections.sort(studentList, (o1, o2) -> o1.getScore() - o2.getScore());
// 写法4
Collections.sort(studentList, Comparator.comparingInt(Student::getScore));
// 写法5,推荐
studentList.sort(Comparator.comparingInt(Student::getScore));

// 数组排序
Arrays.sort(strArray);

list对象多字段排序

1
2
3
4
5
6
7
8
// 先按照score降序排列,再按照name升序排列
// 写法1
list.stream().sorted(Comparator.comparing(Student::getScore).reversed().thenComparing(Student::getName));
// 写法2
list.stream().sorted(Comparator.comparing(Student::getScore, Comparator.reverseOrder()).thenComparing(Student::getName));

// 及早求值排序
versionList.sort((a, b) -> b.getUpdateTime().compareTo(a.getUpdateTime()));

字典排序拼接字符串用作签名

1
2
3
4
5
6
String sortedContent = data.entrySet().stream()
.filter(key -> !Constants.FIELD_SIGN.equals(data.get(key)))
.filter(key -> StringUtils.isNoneBlank(key.getValue()))
.sorted(Map.Entry.comparingByKey())
.map(entry -> entry.getKey() + "=" + StringUtils.trim(entry.getValue()))
.collect(Collectors.joining("&"));

Optional处理空值

1
2
3
4
5
6
7
8
9
10
11
12
13
// 避免if判空,空值返回orElse的值
List<ChannelResponse.ChannelParameter> channelParameters = Optional.ofNullable(response)
.map(ChannelResponse::getChannelParameters)
.orElse(Collections.emptyList());

// 流中使用流,max函数
String latestVal = Optional.ofNullable(channelParameters)
.map(data -> data.stream()
.filter(v -> name.equals(v.getName()))
.max(Comparator.comparing(GetChannelParametersResponse.ChannelParameter::getVersion))
.map(GetChannelParametersResponse.ChannelParameter::getValue)
.get())
.orElse(null);

Comparable与Java8的Comparator区别?
多层排序?
Arrays类使用
使用各套测试框架,每个框架都要实现一定的测试场景
Mockito测试框架

Runtime.getRuntime().availableProcessors()
Arrays.parallelSetAll(array, i -> i);

数组上的并行化操作:parallelPrefix, parallelSetAll, parallelSort

javafx.util.Pair使用

声明:本站所有文章均为原创或翻译,遵循署名 - 非商业性使用 - 禁止演绎 4.0 国际许可协议,如需转载请确保您对该协议有足够了解,并附上作者名 (Tsukasa) 及原文地址