关于TemporalAdjuster引发的思考

前言

我在翻阅java8 DateTime API源码的时候,然后看到源码中一种写法:
首先,看一下LocalDateTime 类中的LocalDateTime with(TemporalAdjuster adjuster)方法的源代码:

@Override
public LocalDateTime with(TemporalAdjuster adjuster) {
    // optimizations
    if (adjuster instanceof LocalDate) {
        return with((LocalDate) adjuster, time);
    } else if (adjuster instanceof LocalTime) {
        return with(date, (LocalTime) adjuster);
    } else if (adjuster instanceof LocalDateTime) {
        return (LocalDateTime) adjuster;
    }
    return (LocalDateTime) adjuster.adjustInto(this);
}

其中,TemporalAdjuster 是一个函数式接口。

@FunctionalInterface
public interface TemporalAdjuster {
	Temporal adjustInto(Temporal temporal);
}

上述with()方法需要调用接口中adjuster.adjustInto(this)方法。
然后,按照一般情况下,我们写代码就需要自定义Lambda表达式实现adjustInto()方法。
但是,我神奇的发现,java8中还有TemporalAdjusters这个类。TemporalAdjusters这个类相当于一个工具类,提供很多常用的静态方法返回TemporalAdjuster的实现。

public final class TemporalAdjusters {
    private TemporalAdjusters() {
    }
    
    public static TemporalAdjuster ofDateAdjuster(UnaryOperator<LocalDate> dateBasedAdjuster) {
        Objects.requireNonNull(dateBasedAdjuster, "dateBasedAdjuster");
        return (temporal) -> {
            LocalDate input = LocalDate.from(temporal);
            LocalDate output = dateBasedAdjuster.apply(input);
            return temporal.with(output);
        };
    }

    public static TemporalAdjuster firstDayOfMonth() {
        return (temporal) -> temporal.with(DAY_OF_MONTH, 1);
    }

    public static TemporalAdjuster lastDayOfMonth() {
        return (temporal) -> temporal.with(DAY_OF_MONTH, temporal.range(DAY_OF_MONTH).getMaximum());
    }

    public static TemporalAdjuster firstDayOfNextMonth() {
        return (temporal) -> temporal.with(DAY_OF_MONTH, 1).plus(1, MONTHS);
    }

    public static TemporalAdjuster firstDayOfYear() {
        return (temporal) -> temporal.with(DAY_OF_YEAR, 1);
    }
    // ......省略
}

那么,我们如何使用呢?

LocalDateTime localDateTime = LocalDateTime.now();
localDateTime.with(TemporalAdjusters.firstDayOfMonth());

我们可以看到,TemporalAdjuster作为参数传入方法中。
然后我们在使用with()方法时,就可以
(1) 通过TemporalAdjusters工具类构建TemporalAdjuster参数
(2) 通过LocalDateTime传入TemporalAdjuster中定义的方法参数。
(3) 这样,常用方法就组织起来了
其实,就是相当于java帮我们定义了一些TemporalAdjuster的常用实现。所以我们也还是可以根据方法定义格式自定义Lambda来实现。
我把这个归为一个编程小技巧吧。

另外,发现源码中好多地方是这么个实现方式。

线程池中:Executors、Executor、ExecutorService

Stream流中:Collectors、Collector


版权声明:本文为qq_29698805原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。