Java 获取 String CompareTo 作为比较器对象

问题描述 投票:0回答:13

我想通过 String.CompareTo 比较器对静态字符串数组进行排序和二分搜索。

问题是排序和二分查找都需要传入 Comparator 对象 -- 那么如何传入内置的字符串比较器呢?

java string object comparator
13个回答
50
投票

您可以编写自己的比较器

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

48
投票

基于 java.util.Comparator.comparing(...)的 Java 8 解决方案:

Comparator<String> c = Comparator.comparing(String::toString);

Comparator<String> c = Comparator.comparing((String x) -> x);

21
投票

Arrays
类有
sort()
binarySearch()
的版本,它们不需要
Comparator.
例如,您可以使用
Arrays.sort()
的版本,它只需要一个对象数组
。这些方法调用数组中对象的
compareTo()
方法。


19
投票

好吧,这是几年后的事了,但在 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。


14
投票

如果您确实需要

Comparator
,并且您已经使用
Guava
,则可以使用
Ordering.natural()


11
投票

这是任何类型

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

10
投票

再次强调,只要对象的类型是可比较的,就不需要

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

6
投票

此外,如果您想要不区分大小写的比较,在最新版本的 Java 中,

String
类包含一个名为
public static final
CASE_INSENSITIVE_ORDER
字段,其类型为
Comparator<String>
,正如我最近发现的那样。因此,您可以使用
String.CASE_INSENSITIVE_ORDER
来完成您的工作。


3
投票

我们可以使用 String.CASE_INSENSITIVE_ORDER 比较器以不区分大小写的顺序比较字符串。

Arrays.binarySearch(someStringArray, "The String to find.",String.CASE_INSENSITIVE_ORDER);

3
投票

要将 Mike Nakis 的好答案概括为

String.CASE_INSENSITIVE_ORDER
,您还可以使用:

Collator.getInstance();

参见配页器


0
投票

我发现最干净的方法是使用 lambda 表达式

像这样:

strings.sort((a, b) -> a.compareTo(b));


如果你想了解更多——

在 javascript 或其他函数式语言中,我们可以简单地传递一个函数作为参数,即

compareTo
本身就是一个
Comparator

在java中,函数不是一等公民。因此,您需要将其包装在一个子类

Comparator
的类中,并将该方法定义为该类的 only 方法。

当然,它看起来很奇怪而且冗长,b/c OOP 并不是为了做这样的事情而设计的。 Lambda 表达式在幕后正是执行此操作(子类化、定义方法),尽管表达式本身看起来与函数式语言中的相同。


-1
投票

关于Nambari的答案有一个错误。如果使用双等号 == 比较值,程序将永远不会到达比较方法,除非有人使用 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);
    }

附注感谢您的评论;)


-2
投票

您可以使用

StringUtils.compare("a", "b")

© www.soinside.com 2019 - 2024. All rights reserved.