Ответ 1
Класс Arrays
имеет версии sort()
и binarySearch()
, для которых не требуется Comparator.
Например, вы можете использовать версию из Arrays.sort()
, который просто принимает массив объектов.
Я хотел бы сортировать и бинарно искать статический массив строк с помощью компаратора String.CompareTo.
Проблема заключается в том, что для сортировки и для двоичного поиска требуется, чтобы объект Comparator был передан - Так как мне передать встроенный компаратор строк?
Класс Arrays
имеет версии sort()
и binarySearch()
, для которых не требуется Comparator.
Например, вы можете использовать версию из Arrays.sort()
, который просто принимает массив объектов.
Вы можете написать свой собственный компаратор
public class ExampleComparator implements Comparator<String> {
public int compare(String obj1, String obj2) {
if (obj1 == null) {
return -1;
}
if (obj2 == null) {
return 1;
}
if (obj1.equals( obj2 )) {
return 0;
}
return obj1.compareTo(obj2);
}
}
Решение для Java 8 на основе java.util.Comparator.comparing(...):
Comparator<String> c = Comparator.comparing(String::toString);
или
Comparator<String> c = Comparator.comparing((String x) -> x);
Если вы нашли, что вам нужен Comparator
, и вы уже используете Guava
, вы можете использовать Ordering.natural()
.
Это общий Comparator
для любого объекта Comparable
, а не только 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 );
}
}
Как использовать с String
:
Comparator<String> stringComparator = DefaultComparator.getInstance();
Опять же, не нужен компаратор для Arrays.binarySearch(Object[] a, Object key)
, если типы объектов сопоставимы, но с лямбда-выражениями это становится проще.
Просто замените компаратор ссылкой на метод: String::compareTo
например:.
Arrays.binarySearch(someStringArray, "The String to find.", String::compareTo);
Вы также можете использовать
Arrays.binarySearch(someStringArray, "The String to find.", (a,b) -> a.compareTo(b));
но даже до лямбда всегда были анонимные классы:
Arrays.binarySearch(
someStringArray,
"The String to find.",
new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
Кроме того, если вы хотите нечувствительность к регистру, в последних версиях Java класс String
содержит поле public static final
, называемое CASE_INSENSITIVE_ORDER
, которое имеет тип Comparator<String>
, как я недавно узнал. Таким образом, вы можете выполнить свою работу, используя String.CASE_INSENSITIVE_ORDER
.
Хорошо, это несколько лет спустя, но с помощью java 8 вы можете использовать Comparator.naturalOrder():
http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#naturalOrder--
Из javadoc:
static <T extends Comparable<? super T>> Comparator<T> naturalOrder()
Возвращает компаратор, который сравнивает объекты Comparable в естественном порядке. Возвращаемый компаратор сериализуется и генерирует исключение NullPointerException при сравнении нулей.
Мы можем использовать компаратор String.CASE_INSENSITIVE_ORDER для сравнения строк в нечувствительном к регистру порядке.
Arrays.binarySearch(someStringArray, "The String to find.",String.CASE_INSENSITIVE_ORDER);
Чтобы обобщить хороший ответ Майка Накиса на String.CASE_INSENSITIVE_ORDER
, вы также можете использовать:
Collator.getInstance();
См. Collator
Относительно Nambari answer произошла ошибка. Если вы сравниваете значения, используя знак двойного равенства ==, программа никогда не будет использовать метод сравнения, если только кто-то не будет использовать ключевое слово новое, чтобы создать объект String, который не является наилучшей практикой. Это может быть немного лучше:
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. Спасибо за комментарии;)