【发布时间】:2012-08-02 00:49:06
【问题描述】:
我想通过 String.CompareTo 比较器对静态字符串数组进行排序和二进制搜索。
问题是排序和二分查找都需要传入一个Comparator对象——那么我该如何传入内置的字符串比较器呢?
【问题讨论】:
标签: java string object comparator
我想通过 String.CompareTo 比较器对静态字符串数组进行排序和二进制搜索。
问题是排序和二分查找都需要传入一个Comparator对象——那么我该如何传入内置的字符串比较器呢?
【问题讨论】:
标签: java string object 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);
}
}
【讨论】:
Comparator 是一个泛型类型,所以ExampleComparator 可能应该实现Comparator<String> 以避免警告。
-1以防obj1==null && obj2==null吗?
obj1 == obj2 则为 true,因此当两者都等于 null 时,结果为 0!
基于java.util.Comparator.comparing(...)的Java 8解决方案:
Comparator<String> c = Comparator.comparing(String::toString);
或
Comparator<String> c = Comparator.comparing((String x) -> x);
【讨论】:
Arrays 类有 sort() 和 binarySearch() 的版本,它们不需要 Comparator. 例如,您可以使用 the version of Arrays.sort() which just takes an array of objects。这些方法调用数组中对象的compareTo()方法。
【讨论】:
如果您确实需要Comparator,并且您已经使用Guava,则可以使用Ordering.natural()。
【讨论】:
好吧,这是几年后的事了,但是使用 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。
【讨论】:
这是一个通用的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) 的比较器,但现在使用 lambda 表达式更容易。
只需将比较器替换为方法参考:String::compareTo
例如:
Arrays.binarySearch(someStringArray, "The String to find.", String::compareTo);
你也可以使用
Arrays.binarySearch(someStringArray, "The String to find.", (a,b) -> a.compareTo(b));
但即使在 lambda 之前,也总是存在匿名类:
Arrays.binarySearch(
someStringArray,
"The String to find.",
new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
【讨论】:
另外,如果你想要不区分大小写的比较,在最近的 Java 版本中,String 类包含一个名为 CASE_INSENSITIVE_ORDER 的 public static final 字段,它的类型是 Comparator<String>,正如我最近发现的那样。因此,您可以使用 String.CASE_INSENSITIVE_ORDER 完成您的工作。
【讨论】:
我们可以使用 String.CASE_INSENSITIVE_ORDER 比较器以不区分大小写的顺序比较字符串。
Arrays.binarySearch(someStringArray, "The String to find.",String.CASE_INSENSITIVE_ORDER);
【讨论】:
【讨论】:
关于 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);
}
附:感谢 cmets ;)
您可以使用StringUtils.compare("a", "b")
【讨论】:
StringUtils属于哪个包。我的 IDE 列出了 10 个不同的。对我来说,答案适用于org.apache.commons.lang3.StringUtils。