【问题标题】:Java get String CompareTo as a comparator objectJava 获取 String CompareTo 作为比较器对象
【发布时间】:2012-08-02 00:49:06
【问题描述】:

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

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

【问题讨论】:

    标签: java string object comparator


    【解决方案1】:

    您可以编写自己的比较器

    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&lt;String&gt; 以避免警告。
    • 对于字符串比较器,在比较它们之前记住小写(或大写)字符串,否则你应该得到这个顺序 A-Za-z
    • 也需要实现equals()。
    • 你确定你应该返回-1以防obj1==null &amp;&amp; obj2==null吗?
    • 基于 @towi 在 2017 年 11 月 24 日的评论:如果 obj1 == obj2 则为 true,因此当两者都等于 null 时,结果为 0!
    【解决方案2】:

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

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

    或

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

    【讨论】:

    • 或 Comparator.comparing(Function.identity())
    【解决方案3】:

    Arrays 类有 sort() 和 binarySearch() 的版本,它们不需要 Comparator. 例如,您可以使用 the version of Arrays.sort() which just takes an array of objects。这些方法调用数组中对象的compareTo()方法。

    【讨论】:

      【解决方案4】:

      如果您确实需要Comparator,并且您已经使用Guava,则可以使用Ordering.natural()。

      【讨论】:

        【解决方案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。

        【讨论】:

        • 始终欢迎提供潜在答案的链接,但请在此处添加最重要的部分,以防链接被删除。
        【解决方案6】:

        这是一个通用的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();
        

        【讨论】:

        • @Sharcoux 我明白了! C-:=
        • 最好将以下代码添加到该类: public static > Comparator getReversedInstance() { return Collections.reverseOrder((Comparator) getInstance ()); }
        【解决方案7】:

        同样,只要对象的类型具有可比性,就不需要 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);
                            }
                        });
        

        【讨论】:

          【解决方案8】:

          另外,如果你想要不区分大小写的比较,在最近的 Java 版本中,String 类包含一个名为 CASE_INSENSITIVE_ORDER 的 public static final 字段,它的类型是 Comparator&lt;String&gt;,正如我最近发现的那样。因此,您可以使用 String.CASE_INSENSITIVE_ORDER 完成您的工作。

          【讨论】:

          • @tallseth 这是正确的答案仅如果您对不区分大小写的搜索感兴趣,并且您使用的是最新版本的 java。如果你需要的是区分大小写的搜索,或者你被一些旧版本的 java 卡住了,那么这不是你的正确答案。
          【解决方案9】:

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

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

          【讨论】:

            【解决方案10】:

            要使用String.CASE_INSENSITIVE_ORDER 概括 Mike Nakis 的好答案,您还可以使用:

            Collator.getInstance();
            

            见Collator

            【讨论】:

              【解决方案11】:

              关于 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 ;)

              【讨论】:

              • 虽然此代码可能会回答问题,但提供有关 why 和/或 如何 回答问题的额外上下文将显着改善其长期价值。请edit你的答案添加一些解释。
              • 这与 Nambari 的 answer 有什么不同?
              【解决方案12】:

              您可以使用StringUtils.compare("a", "b")

              【讨论】:

              • 应该声明StringUtils属于哪个包。我的 IDE 列出了 10 个不同的。对我来说,答案适用于org.apache.commons.lang3.StringUtils。
              猜你喜欢
              • 1970-01-01
              • 2016-10-22
              • 2020-03-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-12-11
              相关资源
              最近更新 更多