Мин / Макс функция с двумя сопоставимыми

У меня есть следующий фрагмент:

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

Это похоже на Math.min(a, b), но определено на Comparable,

Я знаю, что троичный оператор уже довольно короткий, но я не могу встроить выражения для a а также b и я думаю, что min(a, b) соответственно max(a, b) легче понять.

Я знаю, что есть несколько потоков, соответственно. функции коллекции для набора значений, таких как:

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

Это помогло бы встроить выражения, но мне все еще трудно читать и слишком много накладных расходов для такой маленькой задачи.

На данный момент я использую свою собственную служебную функцию, но мне интересно:

Как найти минимум два сопоставимых в удобочитаемом и библиотечно-независимом виде без слишком большого снижения производительности?

5 ответов

  1. От java.util.Collections: Collections.max() а также Collections.min()

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

  1. От org.apache.commons.lang.ObjectUtils: ObjectUtils.max() а также ObjectUtils.min()

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

Я создал свой собственный вспомогательный класс, который расширяет Comparable от min, max, isLessThan, isLessOrEqualTo, isGreaterThan а также isGreaterOrEqualTo:

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;
  }

}

min а также max методы, которые я использую для любого сопоставимого:

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)) {
  ...
}

Сторонние решения

Collections имеет max(collection) а также min(collection) методы, которые делают то, что вы хотите.

Приносить целую новую библиотеку только для того, чтобы встроить одну простую операцию, может быть излишним, если у вас в смеси нет Apache Commons или Guava.

ручная работа с потенциально опасным литьем без литья

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; 
}

Библиотека Google Guava имеетComparators.min и Comparators.max методы с версии 30.0:

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

С использованием Stream

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

Обратите внимание, что обычно вы не звоните get() и назначить, но использовать ifPresent(min -> ...)вместо. Но в этом случае вы можете доверять присутствию значения, поскольку поток не пуст.

Другие вопросы по тегам