用于String和Integer参数的Java compareTo

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

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执行此操作。

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

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

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

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

以可Comparable为例。

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

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

 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的文档在这里 ,你真的应该遵循合同。

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

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

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

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

这是因为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并忽略第一个String中的D.

所以也许我们需要类似下面的东西

 class StringNumericComparator implements Comparator { @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; } }