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?

0

12 Answers

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); } } 
5

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); 
2

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.

0

Ok this is a few years later but with java 8 you can use Comparator.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.

1

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

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(); 
2

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); } }); 

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.

1

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); 

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

Collator.getInstance(); 

See Collator

Regarding Nambari's answer 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 ;)

2

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

1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy