如何将 .min() 或 .max() 作为流的方法参数?

How to put .min() or .max() as method parameter for a stream?

如何在代码中将 .min().max() 表达式作为方法参数传递:

给出的代码:

private LocalDate getMaxDate() {
    LocalDate maxdate = dates.stream()
              .max( Comparator.comparing( LocalDate::toEpochDay ) )
              .get();
}

private LocalDate getMinDate() {
    LocalDate maxdate = dates.stream()
              .min( Comparator.comparing( LocalDate::toEpochDay ) )
              .get();
}

我希望拥有的代码:

private LocalDate getDate(SomeType _EXPR_){
        LocalDate maxdate = dates.stream()
                  ._EXPR_( Comparator.comparing( LocalDate::toEpochDay ) )
                  .get();
    }

提示:_EXPR_ 应为 .min(),有时为 .max()

方法是

private LocalDate getDate(Function<Comparator<LocalDate>, BinaryOperator<LocalDate>> f) {
  return dates.stream()
              .reduce(f.apply(Comparator.comparing(LocalDate::toEpochDay)))
              .get();
}

要调用它,请使用

getDate(BinaryOperator::maxBy);
getDate(BinaryOperator::minBy);

小心 NoSuchElementException 可能会抛出 Optional#get

你可以这样传入一个boolean,然后按要求调用Comparator#reversed()

private LocalDate getDate(boolean max) {
    Comparator<LocalDate> comparator = Comparator.comparing(LocalDate::toEpochDay);
    if (!max) comparator = comparator.reversed();
    return dates.stream().max(comparator).get();
}

也可以使用 enum 而不是 boolean 作为参数来实现相同的行为。这可能更利于可读性。

还有一个选项:

private LocalDate getMinOrMaxDate (boolean max) {
    Stream<LocalDate> ds = dates.stream();
    Comparator<LocalDate> comp = Comparator.comparing(LocalDate::toEpochDay);
    return (max ? ds.max(comp) : ds.min(comp)).get();
}

如果我正确理解你的问题,你想通过 .min() resp。 Stream class 中的 .max() 方法。这可以像这样完成:

   private LocalDate getDate(BiFunction<Stream, Comparator<? super LocalDate>, Optional<LocalDate>> _EXPR_){
       return _EXPR_.apply(dates.stream(), Comparator.comparing(LocalDate::toEpochDay)).get();
   }

然后可以用

调用
getDate(Stream::min);
getDate(Stream::max);

这种方法相当不安全,不是很优雅,并且比使用 getMin() 和 getMax() 方法增加了更多的复杂性。为了可读性,可能值得考虑保留这两种方法。

如果您真的想避免重复代码 and/or 生成方法,我可能会采用类似于 cameron1024 建议的解决方案。