Java compareTo for String和Integer参数

时间:2009-05-23 02:54:17

标签: java compareto

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

7 个答案:

答案 0 :(得分:7)

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”。字符'1'在Java使用的字符集中位于'2'之前,因此它在“2”之前排序“10”,就像“bare”在“hare”之前排序一样,因为'b'在'之前' H”。

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

答案 1 :(得分:2)

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

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

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

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

答案 2 :(得分:0)

获取Comparable

的实例

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

答案 3 :(得分:0)

你描述的内容真的不可能......所以也许你需要发布代码。以下是我对你所做的解释:

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,你真的应该遵守合同。

答案 4 :(得分:0)

首先,您希望Comparator不是Comparable,因为Comparator接受两个对象,而Comparable将当前对象与传入的对象进行比较,并且您无法更改String或Integer上的compareTo()方法,因此: / p>

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

答案 5 :(得分:0)

假设您真正的意思是将整数转换为字符串,然后进行比较,这将无效。例如,假设您有整数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) {
    ....
}

为什么我会这样?因为你所说的是得到错误的结果,而不是谈论获得例外。如果你实际上得到了例外,那么其他海报是正确的,因为投射不起作用。

答案 6 :(得分:0)

正是因为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;
    }
}