ObjectUtils { @SuppressWarnings("unchecked") public static int compare(Object leftObj, Object rightObj) { if (leftObj == null && rightObj == null) { return 0; } if (leftObj == null) { return 1; } if (rightObj == null) { return -1; } if (leftObj instanceof Stream && rightObj instanceof Stream) { return compareStreams((Stream) leftObj, (Stream) rightObj); } if (leftObj instanceof Stream) { leftObj = ((Stream) leftObj).collect(Collectors.toList()); } if (rightObj instanceof Stream) { rightObj = ((Stream) rightObj).collect(Collectors.toList()); } if (leftObj instanceof Collection && rightObj instanceof Collection) { return compareCollections((Collection) leftObj, (Collection) rightObj); } if (!(leftObj instanceof Comparable)) { throw new ClassCastException(leftObj.getClass().getName() + " does not implement " + Comparable.class.getName()); } Comparable left = (Comparable) leftObj; try { if (leftObj instanceof Number && rightObj instanceof Number) { Number leftNumber = (Number) leftObj; Number rightNumber = (Number) rightObj; if (leftObj instanceof Double || leftObj instanceof Float || rightObj instanceof Double || rightObj instanceof Float) { return Double.compare(leftNumber.doubleValue(), rightNumber.doubleValue()); } return Long.compare(leftNumber.longValue(), rightNumber.longValue()); } if (left instanceof Number && !(rightObj instanceof Number)) { return -1; } if (rightObj instanceof Number && !(left instanceof Number)) { return 1; } try { return left.compareTo(rightObj); } catch (Exception ex) { throw new VertexiumCypherException("Could not compare: " + left + " ?= " + rightObj, ex); } } catch (Exception ex) { if (ex instanceof ClassCastException) { throw ex; } throw new VertexiumException( String.format( "Could not compare \"%s\" (%s) to \"%s\" (%s)", leftObj, leftObj == null ? "null" : leftObj.getClass().getName(), rightObj, rightObj == null ? "null" : rightObj.getClass().getName() ), ex ); } }  static boolean equals(Object leftObj, Object rightObj); @SuppressWarnings("unchecked") static int compare(Object leftObj, Object rightObj); static Number addNumbers(Number leftNumber, Number rightNumber); static Number subtractNumbers(Number leftNumber, Number rightNumber); static Number sumNumbers(Stream<?> stream); static Object divideNumbers(Number numerator, Number denominator); static Object modNumbers(Number a, Number b); static Object powerNumbers(Number a, Number b); static Object multiplyNumbers(Number a, Number b); static List<Object> arrayToList(Object arr); static Predicate<T> distinctByDeep(Function<? super T, ?> fn);  }
@Test public void testCompare() { assertEquals(0, ObjectUtils.compare(null, null)); assertEquals(1, ObjectUtils.compare(null, 1)); assertEquals(-1, ObjectUtils.compare(1, null)); ArrayList<Integer> list = Lists.newArrayList(1, null); list.sort(ObjectUtils::compare); assertEquals(1, (int) list.get(0)); assertEquals(null, list.get(1)); }