两个 Comparables 的最小/最大函数

Min / max function of two Comparables

我需要找到两个 Comparable 值中较小的一个:

Comparable<C> a = ...;
Comparable<C> b = ...;
Comparable<C> min = a.compareTo(b) <= 0 ? a : b;

这类似于 Math.min(a, b),但对于 Comparable

我知道三元运算符已经很短了,但我无法内联 ab 的表达式,我认为 min(a, b)max(a, b) 更容易理解。

我知道有几个函数对 StreamCollection 值进行操作,例如:

Stream.of(a, b).min(Comparator.naturalOrder())

这将有助于内联表达式,但我仍然觉得它很难阅读,而且对于这么小的任务来说开销有点大。

目前我正在使用我自己的实用函数,但我很想知道是否有用于此目的的现有函数。如何以一种可读且独立于库的方式找到两个 Comparable 值中的最小值而不需要太多性能开销?

  1. 来自 java.util.CollectionsCollections.max() and Collections.min()

    Comparable<C> a = ...;
    Comparable<C> b = ...;
    Comparable<C> min = Collections.min(Arrays.asList(a,b));
    

  1. 来自 org.apache.commons.lang3.ObjectUtils : ObjectUtils.max() and ObjectUtils.min()

    Comparable<C> a = ...;
    Comparable<C> b = ...;
    Comparable<C> min = ObjectUtils.min(a, b);
    

Apache Commons 的开销较小并且能够处理 null 值,但它是第三方库。

3rd方解决方案

Collectionsmax(collection)min(collection) 方法,你想做什么就做什么。

引入全新的库只是为了内联一个简单的操作可能有点矫枉过正,除非你有 Apache CommonsGuava .

手工制作

public <T extends Comparable<T>> T max(T a, T b) { 
    return a.compareTo(b) >= 0 ? a : b; 
}

public <T extends Comparable<T>> T min(T a, T b) { 
    return a.compareTo(b) < 0 ? a : b; 
}

我创建了自己的助手 class,它将 Comparable 扩展了 minmaxisLessThanisLessOrEqualToisGreaterThanisGreaterOrEqualTo:

public interface Ordered<T> extends Comparable<T> {

  static <T extends Comparable<T>> T min(T a, T b) {
    return a.compareTo(b) <= 0 ? a : b;
  }

  static <T extends Comparable<T>> T max(T a, T b) {
    return a.compareTo(b) >= 0 ? a : b;
  }

  default boolean isLessThan(T other) {
    return compareTo(other) < 0;
  }

  default boolean isLessOrEqualTo(T other) {
    return compareTo(other) <= 0;
  }

  default boolean isGreaterThan(T other) {
    return compareTo(other) > 0;
  }

  default boolean isGreaterOrEqualTo(T other) {
    return compareTo(other) >= 0;
  }

}

我用于任何 Comparable 的 minmax 方法:

String first = "a";
String second = "b";
System.out.println(Ordered.min(first, second)); // Prints "a"

对于我自己的 Comparable 实现,我扩展了 Ordered 并将其用于可读性比较。对枚举很有帮助:

public enum Board implements Ordered<Board> {
  NONE,
  BREAKFAST,
  HALF_BOARD,
  FULL_BOARD,
  ALL_INCLUSIVE
}

用法:

Board requestedBoard = ...;
Board availableBoard = ...;
if (requestedBoard.isLessOrEqualTo(availableBoard)) {
  ...
}

30.0 版的 Google Guava library has the Comparators.min and Comparators.max 方法:

Comparable<C> min = Comparators.min(a, b);

使用Stream

Comparable<C> min = Stream.of(a, b).min(Comparable::compareTo).get();

请注意,您通常不会调用 get() 并赋值,而是使用 ifPresent(min -> ...)。但在这种情况下,您可以相信该值存在,因为流不为空。