Java get String CompareTo as a comparator object

JavaStringObjectComparator

Java Problem Overview


I would like to sort and binary search a static array of strings via the String.CompareTo comparator.

The problem is that both sorting, and binary searching requires that a Comparator object be passed in -- So how do I pass in the built in string comparator?

Java Solutions


Solution 1 - Java

You may write your own comparator

public class ExampleComparator  implements Comparator<String> {
  public int compare(String obj1, String obj2) {
    if (obj1 == obj2) {
        return 0;
    }
    if (obj1 == null) {
        return -1;
    }
    if (obj2 == null) {
        return 1;
    }
    return obj1.compareTo(obj2);
  }
}

Solution 2 - Java

Solution for Java 8 based on java.util.Comparator.comparing(...):

Comparator<String> c = Comparator.comparing(String::toString);

or

Comparator<String> c = Comparator.comparing((String x) -> x);

Solution 3 - Java

The Arrays class has versions of sort() and binarySearch() which don't require a Comparator. For example, you can use the version of Arrays.sort() which just takes an array of objects. These methods call the compareTo() method of the objects in the array.

Solution 4 - Java

Ok this is a few years later but with java 8 you can use Comparator.naturalOrder():

http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#naturalOrder--

From javadoc:

static <T extends Comparable<? super T>> Comparator<T> naturalOrder()

Returns a comparator that compares Comparable objects in natural order. The returned comparator is serializable and throws NullPointerException when comparing null.

Solution 5 - Java

If you do find yourslef needing a Comparator, and you already use Guava, you can use Ordering.natural().

Solution 6 - Java

This is a generic Comparator for any kind of Comparable object, not just String:

package util;

import java.util.Comparator;

/**
 * The Default Comparator for classes implementing Comparable.
 *
 * @param <E> the type of the comparable objects.
 *
 * @author Michael Belivanakis (michael.gr)
 */
public final class DefaultComparator<E extends Comparable<E>> implements Comparator<E>
{
    @SuppressWarnings( "rawtypes" )
    private static final DefaultComparator<?> INSTANCE = new DefaultComparator();

    /**
     * Get an instance of DefaultComparator for any type of Comparable.
     *
     * @param <T> the type of Comparable of interest.
     *
     * @return an instance of DefaultComparator for comparing instances of the requested type.
     */
    public static <T extends Comparable<T>> Comparator<T> getInstance()
    {
        @SuppressWarnings("unchecked")
        Comparator<T> result = (Comparator<T>)INSTANCE;
        return result;
    }

    private DefaultComparator()
    {
    }

    @Override
    public int compare( E o1, E o2 )
    {
        if( o1 == o2 )
            return 0;
        if( o1 == null )
            return 1;
        if( o2 == null )
            return -1;
        return o1.compareTo( o2 );
    }
}

How to use with String:

Comparator<String> stringComparator = DefaultComparator.getInstance();

Solution 7 - Java

Again, don't need the comparator for Arrays.binarySearch(Object[] a, Object key) so long as the types of objects are comparable, but with lambda expressions this is now way easier.

Simply replace the comparator with the method reference: String::compareTo

E.g.:

Arrays.binarySearch(someStringArray, "The String to find.", String::compareTo);

You could also use

Arrays.binarySearch(someStringArray, "The String to find.", (a,b) -> a.compareTo(b));

but even before lambdas, there were always anonymous classes:

Arrays.binarySearch(
                someStringArray,
                "The String to find.",
                new Comparator<String>() {
                    @Override
                    public int compare(String o1, String o2) {
                        return o1.compareTo(o2);
                    }
                });

Solution 8 - Java

Also, if you want case-insensitive comparison, in recent versions of Java the String class contains a public static final field called CASE_INSENSITIVE_ORDER which is of type Comparator<String>, as I just recently found out. So, you can get your job done using String.CASE_INSENSITIVE_ORDER.

Solution 9 - Java

We can use the String.CASE_INSENSITIVE_ORDER comparator to compare the strings in case insensitive order.

Arrays.binarySearch(someStringArray, "The String to find.",String.CASE_INSENSITIVE_ORDER);

Solution 10 - Java

To generalize the good answer of Mike Nakis with String.CASE_INSENSITIVE_ORDER, you can also use :

Collator.getInstance();

See [Collator][1]

[1]: https://docs.oracle.com/javase/7/docs/api/java/text/Collator.html "Collator"

Solution 11 - Java

Regarding Nambari's [answer][1] there was a mistake. If you compare values using double equal sign == program will never reach compare method, unless someone will use new keyword to create String object which is not the best practice. This might be a bit better solution:

public int compare(String o1, String o2) {
        if (o1 == null && o2 == null){return 0;}
        if (o1 == null) { return -1;}
        if (o2 == null) { return 1;}
        return o1.compareTo(o2);
    }

P.S. Thanks for comments ;)

[1]: https://stackoverflow.com/a/11804763/369450 "answer"

Solution 12 - Java

You can use the StringUtils.compare("a", "b")

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGeorges Oates LarsenView Question on Stackoverflow
Solution 1 - JavakosaView Answer on Stackoverflow
Solution 2 - JavaAntonioView Answer on Stackoverflow
Solution 3 - JavaCode-ApprenticeView Answer on Stackoverflow
Solution 4 - JavabrunestoView Answer on Stackoverflow
Solution 5 - JavaMichael Brewer-DavisView Answer on Stackoverflow
Solution 6 - JavaMike NakisView Answer on Stackoverflow
Solution 7 - JavaJoseph NieldsView Answer on Stackoverflow
Solution 8 - JavaMike NakisView Answer on Stackoverflow
Solution 9 - JavaSudhakarView Answer on Stackoverflow
Solution 10 - JavaSharcouxView Answer on Stackoverflow
Solution 11 - JavaRafał JankowskiView Answer on Stackoverflow
Solution 12 - JavaJoão Pedro SchmittView Answer on Stackoverflow