JDK8流式编程

Posted by 拜占庭 on 2022-04-02

JDK8 流式编程

Lambda 表达式

  • Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性
  • Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)
  • 使用 Lambda 表达式可以使代码变的更加简洁紧凑。

Optional 解决NULL问题

1
if (someVariable == null){ // do something} else{ // do something else}

既然我们无法避免这个单调的过程,那我们可以思考有什么方法,来优化这个过程?

Optional 为我们提供了一组完整的方法,为我们处理以下多种场景:

如果为空,则返回某个值
如果为null,则引发异常
如果为空,则执行计算并返回结果值
如果为空,则运行某函数

  • <如果为空,则返回某个值>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    空值检测方式

    private String getString() {
    String result = getStringFromDB();
    if (result == null)
    return "It's empty";
    else return result; }

    Optional处理方式

    private String getStringWithTrick() { return Optional.ofNullable(getStringFromDB()).orElse("It's empty"); }
  • <如果为null,则引发异常>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    空值检测方式

    private String getString() throws Exception{
    String result = getStringFromDB();
    if (result == null) throw new Exception();
    else return result; }

    Optional处理方式
    private String getStringWithTrick() throws Exception{
    return Optional.ofNullable(getStringFromDB()).orElseThrow(Exception::new); }
  • <如果为空,则运行某函数 / 执行计算并返回结果值>

1
2
3
4
5
6
7
8
9
10
11
12
13
空值检测方式
private String getString() {
String result = getStringFromDB();
if (result == null)
return doCalculation();
else {
return result;
}

Optional处理方式
private String getStringWithTrick() {
return Optional.ofNullable(getStringFromDB()).orElseGet(this::doCalculation);
}

基于这些例子,Optional可以涵盖于代码的方方面面,同时可以使代码更加优雅整洁。

  • orElse 与 orElseGet 区别

    使用 Optional.ofNullable(obj).orElse 时,无论 obj 是否为 null,都会执行 orElse 的方法;
    使用 Optional.ofNullable(obj).orElseGet 时,只有 obj 为 null,才会执行 orElseGet 里的方法,orElseGet方法不会执行,因为他使用的Supplier函数接口。

当值是函数或者需要计算时建议使用orElseGet,当值是基础类型值时就用orElse

1
2
3
4
5
6
7
8
9
// 使用orElse的情形,数值,字符串,引用
orElse(0)
orElse("unKnown");
orElse(ref);

// 使用orElseGet函数调用
orElseGet(Collections.emptyMap);
orElseGet(Collections.emptyList);
orElseGet(RandomUtils::nextInt)

实例:

1
2
3
4
5
6
7

BigDecimal result = Optional.ofNullable(taxBurdenModelList).orElseGet(ArrayList::new)
.stream()
.filter(t -> Objects.nonNull(t.getTaxBurden())
&& t.getEndPeriod().startsWith(formatePeriod))
.findFirst().map(x -> x.getTaxBurden().divide(ONE_HUNDRED, 4, BigDecimal.ROUND_HALF_UP))
.orElse(null);

函数式接口 Supplier

1
2
3
4
5
6
7
8
9
10
@FunctionalInterface
public interface Supplier<T> {

/**
* Gets a result.
*
* @return a result
*/
T get();
}

findFirst 和 findAny

在Java 8 Stream中, findFirst()返回Stream中的第一个元素,而findAny()返回Stream中的任何元素。