【问题标题】:Java compareTo for String and Integer arguments用于字符串和整数参数的 Java compareTo
【发布时间】:2009-05-23 02:54:17
【问题描述】:

我正在实现冒泡排序算法,我希望它能够同时接受IntegerString 参数。我将所有输入转换为字符串并使用compareTo 方法将转换为字符串的整数与字符串进行比较。使用 compareTo 比较转换后的整数时,我得到的答案不正确。我做错了什么?

【问题讨论】:

    标签: java compareto


    【解决方案1】:

    Integer.compareTo 对数字进行数字排序。这就是你想要的。

    String.compareTo 按字典顺序对字符串进行排序;也就是说,按字母顺序。

    我记得在 Windows 3.1 中,我的数码相机中的照片文件夹是这样排列的:PHOTO1、PHOTO10、PHOTO100、PHOTO2、PHOTO20、PHOTO3 等等。 Windows XP 对它们的排序更符合您的预期:PHOTO1、PHOTO2、PHOTO3 等。这是因为它对表示数字的字符串有特殊的排序规则。

    在字典顺序中,一个字符串 A 中的每个字符都与另一个字符串 B 中的对应字符进行比较。对于两个字符串中的每个对应字符:

    • 如果 A 的当前字符按字典顺序小于(在字母表中位于之前)B 的字符,则 A 位于 B 之前。
    • 如果 B 的字符小于 A 的字符,则 B 在 A 之前。
    • 如果这两个字符相同,那么我们还不知道。选中下一个。
    • 如果其中一个字符串中没有更多字符,则较短的字符排在较长的字符串之前。
    • 如果两个字符串中都没有字符了,那么它们就是同一个字符串。

    这里的第四点是你得到错误答案的原因,假设 Eddie 对你的问题的分析是正确的。

    考虑字符串“10”和“2”。字典顺序将分别查看每个字符的第一个字符,“1”和“2”。在 Java 使用的字符集中,字符 '1' 排在 '2' 之前,因此它将“10”排在“2”之前,就像“bare”排在“hare”之前一样,因为 'b' 排在 ' 之前h'。

    我建议您在排序之前将字符串转换为整数。使用 Integer.parseString 来执行此操作。

    【讨论】:

    • 将字符串转换为整数对我来说也更合理。当然,它只有在所有字符串实际上都是整数的字符串表示时才有效。
    • 漂亮的例子很好的答案。
    【解决方案2】:

    您确定要将整数和字符串混合在同一个列表中吗?如果是这样,整数是小于还是大于字符串?这个特定的排序标准是什么?

    您还可以创建一个冒泡排序方法,对不同的 Integer 列表和 String 列表(以及任何其他类的列表)进行排序。为此,您可以使用泛型。例如:

    public static <T> void bubbleSort(List<T> elements, Comparator<T> comparator) {
        // your implementation
    }
    

    您使用comparator 参数来比较elements,这就是为什么它们可以是整数或字符串(不能同时是两者)。编译器不会让你[没有任何警告]传递一个类的对象列表和不同类的比较器,所以比较总是有效的。

    【讨论】:

      【解决方案3】:

      获取Comparable 的实例。

      字符串不能真正转换为整数,也没有比较方法。

      【讨论】:

      • "comparryo" 是一个错字。如果将末尾的“ry”向左移动一个键,则会得到“et”,它会给出“compareto”。
      【解决方案4】:

      您所描述的实际上是不可能的......所以也许您需要发布代码。这是我对你在做什么的解释:

      public int compareTo(final Object o)
      {
          final String str;
      
          str = (String)o; // this will crash if you pass it an Integer.
      
          // rest of the code.
      }
      

      compareTo 的文档是here,你真的应该遵守合同。

      【讨论】:

        【解决方案5】:

        首先,您需要Comparator 而不是Comparable,因为 Comparator 需要两个对象,而 Comparable 将当前对象与传入的一个对象进行比较,您无法更改 String 或 Integer 上的 compareTo() 方法,因此:

        public class CompareIntegersAsStrings implements Comparator {
          public int compare(Object o1, Object o2) {
            return o1.toString().compareTo(o2.toString());
          }
        }
        

        【讨论】:

        • 这会失败,因为“10”是“小于”2。
        • 这就是我阅读问题的方式:他想将整数作为字符串进行比较。如果他想自动将字符串转为整数,并进行数值比较,那当然是不同的。
        【解决方案6】:

        假设您真正的意思是将整数转换为字符串,然后进行比较,这是行不通的。例如,假设您有整数 1234 和整数 1 和整数 2。如果将这些转换为字符串并比较它们,您将得到顺序:

        1
        1234
        2
        

        这对于 ASCII 排序是正确的,对于数字排序是不正确的。也就是说,我假设您的代码执行以下操作:

        public int myCompare(Integer a1, Integer a2) {
            myCompare(String.valueOf(a1), String.valueOf(a2));
        }
        
        public int myCompare(String a1, String a2) {
            ....
        }
        

        我为什么要这样假设?因为您在谈论获得不正确的结果而不是谈论获得异常。如果您实际上得到了例外,那么其他海报是正确的,即强制转换不起作用。

        【讨论】:

          【解决方案7】:

          这是因为 String 类中的以下 java API 代码仅比较两个字符串中字符的最小长度。

          public int compareTo(String anotherString) {
              int len1 = value.length;
              int len2 = anotherString.value.length;
              int lim = Math.min(len1, len2); //**HERE**
              char v1[] = value;
              char v2[] = anotherString.value;
          
              int k = 0;
              while (k < lim) {
                  char c1 = v1[k];
                  char c2 = v2[k];
                  if (c1 != c2) {
                      return c1 - c2;
                  }
                  k++;
              }
              return len1 - len2;
          }
          

          如果我们用这个api来比较

          String first = "ABCD"; 
          String second = "ABZ"; 
          System.out.println("" + "ABCD".compareTo("ABZ")); //-23
          

          将返回负值,表示 ABCD 小于 ABZ 表示 C 小于 Z 并在第一个字符串中忽略 D。

          所以也许我们需要像下面这样的东西

          class StringNumericComparator implements Comparator<String> {
              @Override
              public int compare(String o1, String o2) {
                  int len1 = o1.length();
                  int len2 = o2.length();
                  if(len1 != len2) {
                      return len1 - len2; //Else iterate all diff lengh chars and SUM it.
                  }
                  int lim = Math.min(len1, len2);
                  char v1[] = o1.toCharArray();
                  char v2[] = o2.toCharArray();
          
                  int k = 0;
                  while (k < lim) {
                      char c1 = v1[k];
                      char c2 = v2[k];
                      if (c1 != c2) {
                          return c1 - c2;
                      }
                      k++;
                  }
                  return 0;
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-11-08
            相关资源
            最近更新 更多