/* * Copyright (c) 2013-2017 Cinchapi Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.cinchapi.concourse.util; import java.util.Comparator; import com.google.common.collect.Ordering; /** * A collection of commonly used comparator instances. These comparator * instances are easy enough to make, but this class provides them so that there * is a canonical set, which allows us to avoid creating lots of temporary * objects just to do sorting. * * @author Jeff Nelson */ public final class Comparators { /** * Return a {@link Comparator} that always returns {@code 0} when two * objects are equal, but otherwise returns an arbitrary but consistent * ordering for objects during the course of the JVM lifecycle. * * @return the comparator */ public static <T> Comparator<T> equalOrArbitrary() { return new EqualOrArbitraryComparator<T>(); } /** * Return a {@link Comparator} that sorts elements by their natural order if * they are {@link Comparable} and sorts them in an arbitrary, but per * JVM-lifecycle consistent, order if they are not. * * @return the comparator */ public static <T> Comparator<T> naturalOrArbitrary() { return new NaturalOrArbitraryComparator<T>(); } /** * Perform an arbitrary comparison between {@code o1} and {@code o2}. This * method assumes that the two objects are not considered equal. * * @param o1 * @param o2 * @return the comparison value */ private static <T> int arbitraryCompare(T o1, T o2) { return Ordering.arbitrary().compare(o1, o2); } /** * A comparator that sorts strings lexicographically without regards to * case. */ public final static Comparator<String> CASE_INSENSITIVE_STRING_COMPARATOR = new Comparator<String>() { @Override public int compare(String s1, String s2) { return s1.compareToIgnoreCase(s2); } }; /** * A comparator that sorts longs in numerical order. */ public final static Comparator<Long> LONG_COMPARATOR = new Comparator<Long>() { @Override public int compare(Long o1, Long o2) { return Long.compare(o1, o2); } }; private Comparators() {/* noop */} /** * A {@link Comparator} that is similar to {@link Ordering#arbitrary()} in * that in will return an arbitrary but consistent ordering of objects * (during the duration of the JVM lifecycle), unless they are equal, in * which case it returns 0. * * @author Jeff Nelson */ private static class EqualOrArbitraryComparator<T> implements Comparator<T> { @Override public int compare(T o1, T o2) { if(o1 == o2 || o1.equals(o2)) { return 0; } else { return arbitraryCompare(o1, o2); } } } /** * A {@link Comparator} that uses the functionality of the {@link Ordering * @natural()} comparator if the objects are {@link Comparable}. Otherwise, * the functionality is similar to the {@link Ordering#arbitrary()} * comparator. * * * @author Jeff Nelson */ private static class NaturalOrArbitraryComparator<T> implements Comparator<T> { @SuppressWarnings("unchecked") @Override public int compare(T o1, T o2) { if(o1 instanceof Comparable) { return ((Comparable<T>) o1).compareTo(o2); } else { return arbitraryCompare(o1, o2); } } } }