Java get String CompareTo as a comparator object
JavaStringObjectComparatorJava 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")