我想通过String.CompareTo比较器对一个静态字符串数组进行排序和二进制搜索。
问题是排序和二进制搜索都要求传入Comparator对象 - 那么如何传入内置的字符串比较器呢?
答案 0 :(得分:35)
您可以编写自己的比较器
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);
}
}
答案 1 :(得分:26)
基于java.util.Comparator.comparing(...)的Java 8解决方案:
Comparator<String> c = Comparator.comparing(String::toString);
或
Comparator<String> c = Comparator.comparing((String x) -> x);
答案 2 :(得分:18)
Arrays
类的版本为sort()
和binarySearch()
,不需要Comparator.
例如,您可以使用the version of Arrays.sort()
which just takes an array of objects。这些方法调用数组中对象的compareTo()
方法。
答案 3 :(得分:11)
如果您确实发现自己需要Comparator
,并且已使用Guava
,则可以使用Ordering.natural()
。
答案 4 :(得分:10)
对于任何类型的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();
答案 5 :(得分:9)
同样,只要对象类型具有可比性,就不需要Arrays.binarySearch(Object[] a, Object key)
的比较器,但是使用lambda表达式现在更容易了。
只需使用方法参考替换比较器:String::compareTo
E.g:
Arrays.binarySearch(someStringArray, "The String to find.", String::compareTo);
您也可以使用
Arrays.binarySearch(someStringArray, "The String to find.", (a,b) -> a.compareTo(b));
但即使在lambdas之前,总会有匿名课程:
Arrays.binarySearch(
someStringArray,
"The String to find.",
new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
答案 6 :(得分:6)
此外,如果您需要不区分大小写的比较,则在最新版本的Java中,String
类包含名为public static final
的{{1}}字段,其类型为CASE_INSENSITIVE_ORDER
,如我刚刚发现了。因此,您可以使用Comparator<String>
完成工作。
答案 7 :(得分:5)
好的,这是几年后但是使用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对象。 返回的比较器是可序列化的,并在比较null时抛出NullPointerException。
答案 8 :(得分:2)
我们可以使用String.CASE_INSENSITIVE_ORDER比较器来比较不区分大小写的字符串。
Arrays.binarySearch(someStringArray, "The String to find.",String.CASE_INSENSITIVE_ORDER);
答案 9 :(得分:0)
答案 10 :(得分:-1)
关于Nambari的answer,有一个错误。如果您使用双等号 == 比较值,程序将永远不会达到比较方法,除非有人使用 new 创建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。感谢您的评论;)
答案 11 :(得分:-1)
您可以使用StringUtils.compare("a", "b")