org.cinchapi.concourse.util.Comparators.java Source code

Java tutorial

Introduction

Here is the source code for org.cinchapi.concourse.util.Comparators.java

Source

/*
 * The MIT License (MIT)
 * 
 * Copyright (c) 2014 Jeff Nelson, Cinchapi Software Collective
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.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 jnelson
 */
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 jnelson
     */
    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 jnelson
         */
    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);
            }
        }

    }

}