Skip to content

Instantly share code, notes, and snippets.

@hyamamoto
Last active August 11, 2020 08:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save hyamamoto/6762765 to your computer and use it in GitHub Desktop.
Save hyamamoto/6762765 to your computer and use it in GitHub Desktop.
Generic null safe " Comparable.compareTo()" implementations.

Comparing.java : Generic Null-Safe Comparable.compareTo()

Suuuuuuuggggggggggggggah. I've just wasted 5 min only to end up realizing the Guava also does the same thing smarter. But at least I made it Java 6 (GWT/Android) compatible...

Available Methods

  • Comparing.compareTo( Object, Object)
  • Comparing.intCompareTo( Number, Number)
  • Comparing.longCompareTo( Number, Number)
  • Comparing.floatCompareTo( Number, Number)
  • Comparing.doubleCompareTo( Number, Number)
  • Comparing.bigDecimalCompareTo( Number, Number)
  • Comparing.bigDecimalCompareTo( BigDecimal, BigDecimal)
  • Comparing.stringCompareTo( Object, Object)
  • Comparing.stringCompareTo( String, String)

You should also look at ...

  • Apache Commons: ObjectUtils.compare(Object, Object)
  • Guava: ComparisonChain.start()
  • Java 7: Objects.compare(Object)
/**
* Generic null safe {@link Comparable#compareTo(Object)} implementations.
*
* @author Hiroshi Yamamoto
* @see {@link Comparable}
*/
public final class Comparing {
private Comparing() {}
/** Null safe comparison for <code>Numbers</code> as <code>int</code>. */
public static <T extends Number> int intCompareTo(final T n1, final T n2) {
return compareTo(n1 != null ? n1.intValue() : null, n2 != null ? n2.intValue() : null);
}
/** Null safe comparison for <code>Numbers</code> as <code>long</code>. */
public static <T extends Number> int longCompareTo(final T n1, final T n2) {
return compareTo(n1 != null ? n1.longValue() : null, n2 != null ? n2.longValue() : null);
}
/** Null safe comparison for <code>Numbers</code> as <code>float</code>. */
public static <T extends Number> int floatCompareTo(final T n1, final T n2) {
return compareTo(n1 != null ? n1.floatValue() : null, n2 != null ? n2.floatValue() : null);
}
/** Null safe comparison for <code>Numbers</code> as <code>double</code>. */
public static <T extends Number> int doubleCompareTo(final T n1, final T n2) {
return compareTo(n1 != null ? n1.doubleValue() : null, n2 != null ? n2.doubleValue() : null);
}
/** Null safe comparison for <code>Numbers</code> as <code>BigDecimal</code>. */
public static <T extends Number> int bigDecimalCompareTo(final T n1, final T n2) {
return bigDecimalCompareTo(n1 != null ? new BigDecimal(n1.toString()) : null, //
n2 != null ? new BigDecimal(n2.toString()) : null);
}
/** Null safe comparison for <code>BigDecimals</code>. */
public static <T extends Number> int bigDecimalCompareTo(final BigDecimal n1, final BigDecimal n2) {
return compareTo(n1, n2);
}
/**
* Null safe comparison for <code>Objects</code> as <code>String</code>. {@link Object#toString()}
* will be called on each given object.
*/
public static <T> int stringCompareTo(final T obj1, final T obj2) {
return stringCompareTo((String) (obj1 != null ? obj1.toString() : null), //
(String) (obj2 != null ? obj2.toString() : null));
}
/** Null safe comparison for two {@link String} values. */
public static int stringCompareTo(final String str1, final String str2) {
final boolean f1, f2;
return (f1 = str1 == null) ^ (f2 = str2 == null) ? f1 ? -1 : 1 : f1 && f2 ? 0 : str1
.compareToIgnoreCase(str2);
}
/**
* Null safe comparison for <code>Comparables</code>. <br/>
* <b>Be careful when you place this method inside {@link Comparable#compareTo(Object)} as such a
* method call will loop.</b>
**/
public static <T extends Comparable<T>> int compareTo(final T c1, final T c2) {
final boolean f1, f2;
return (f1 = c1 == null) ^ (f2 = c2 == null) ? f1 ? -1 : 1 : f1 && f2 ? 0 : c1.compareTo(c2);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment