I need to find the smaller of two Comparable
values:
Comparable<C> a = ...;
Comparable<C> b = ...;
Comparable<C> min = a.compareTo(b) <= 0 ? a : b;
This is similar to Math.min(a, b)
, but for Comparable
.
I know that the ternary operator is already quite short, but I can't inline the expressions for a
and b
and I think that min(a, b)
and max(a, b)
is easier to understand.
I know that there are several functions that operate on Stream
and Collection
values, like:
Stream.of(a, b).min(Comparator.naturalOrder())
This would help to inline the expressions, but I still find it difficult to read and a bit too much overhead for such a small task.
For the moment I'm using my own utility function, but I'm interested to know if there's an existing function for this purpose. How can one find the minimum of two Comparable
values in a readable and library-independent manner without too much performance overhead?
From java.util.Collections
: Collections.max()
and Collections.min()
Comparable<C> a = ...;
Comparable<C> b = ...;
Comparable<C> min = Collections.min(Arrays.asList(a,b));
From 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 has less overhead and is able to handle null
values, but it is a third party library.
I have created my own helper class, which extends Comparable
by min
, max
, isLessThan
, isLessOrEqualTo
, isGreaterThan
and isGreaterOrEqualTo
:
public interface Ordered<T> extends Comparable<T> {
static <T extends Comparable<? super T>> T min(T a, T b) {
return a.compareTo(b) <= 0 ? a : b;
}
static <T extends Comparable<? super 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;
}
}
The min
and max
methods I use for any Comparable:
String first = "a";
String second = "b";
System.out.println(Ordered.min(first, second)); // Prints "a"
For my own implementations of Comparable
I extend Ordered
and use that one for readable comparisons. Very helpful for enums:
public enum Board implements Ordered<Board> {
NONE,
BREAKFAST,
HALF_BOARD,
FULL_BOARD,
ALL_INCLUSIVE
}
Usage:
Board requestedBoard = ...;
Board availableBoard = ...;
if (requestedBoard.isLessOrEqualTo(availableBoard)) {
...
}
Collections
has max(collection)
and min(collection)
methods, which kind of do what you want.
Bringing whole new library just to inline one simple op might be an overkill, unless you have Apache Commons or Guava in the mix.
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;
}
The Google Guava library has the Comparators.min
and Comparators.max
methods as of version 30.0:
Comparable<C> min = Comparators.min(a, b);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With