Java - 检查一个字符串的ArrayList是否按字母顺序排列

7
我有一个名为account的ArrayList,其中包含字符串。我正在尝试编写一个方法来检查它们是否按顺序排列,并根据它们是否按顺序排列返回true或false。
您会如何处理这个问题?我已经尝试使用for循环检查初始字符,但结果非常糟糕。我创建了一个新的ArrayList并将其设置为原始值,然后对其进行排序并进行比较,但由于它们包含相同的数据,因此它总是返回true。
还有一个额外的快速问题,由于我正在处理字符串,如果要检查一些数字是否按升序/降序排列,该怎么办?通过相同的原理吗?
谢谢!

https://dev59.com/h3A75IYBdhLWcg3w49YR 与 String#compareTo(String) 方法的 Javadoc 结合起来,应该能够帮助你解决问题。 - Robin
1
使用String.compareTo并不意味着按字母顺序排序。需要使用compareToIgnoreCase或某个版本的java.text.Collator - bestsss
正确答案取决于您是真正需要“编写方法”还是“找出列表是否排序”。在第二种情况下,最好不要实际编写方法,而是使用外部库,例如Guava的Ordering类(有关详细信息,请参见我的答案)。只是不要重复造轮子的错误 :) - Piotr Findeisen
6个回答

13

尝试这个(假设你想使用字符串的自然排序进行比较):

String previous = ""; // empty string: guaranteed to be less than or equal to any other

for (final String current: thelist) {
    if (current.compareTo(previous) < 0)
        return false;
    previous = current;
}

return true;

这是由于String实现了Comparable<String>,并且比较将使用字符串的自然顺序进行。


@bestsss 这个循环加上那个最后部分不是看起来更好吗?在前5个字符之后,你已经知道它的意思是不改变列表中的任何元素,所以它只是读取它。这很好。 - dantuch
2
@dantuch,final并不意味着不改变该列表中的任何元素,它只是表示本地变量引用不会改变。更改列表中元素内容需要不可变类(String就是其中之一),它与final无关。for in确保不进行修改,这有点奇怪,因为它适用于iterator,虽然它可能不使用remove(),但这是另一个奇怪的点(将iterator转换为基本上已经弃用的Enumeration)。 - bestsss
@bestsss:确实,foreach循环可以确保这一点,但是仍然可以重复使用引用——使用final关键字可以防止这种情况的发生。 - fge
如果您喜欢使用现成的方法,请使用Guava的“Ordering”类。有关详细信息,请参阅我的答案。 - Piotr Findeisen
@fge,在20多年的时间里,我不记得有一次即使我非常醉酒,错误地重复使用了本地引用/变量。可能会发生,但我仍然认为这极不可能。 - bestsss
显示剩余3条评论

6

如果您不介意使用外部库(Guava),则Ordering可以实现:

boolean isSorted = Ordering.natural().isOrdered(list);

以下内容适用于 String 和其他可比较类型。如果您需要检查某个自定义类型的排序,请使用 Ordering 类中的任何静态工厂方法或其子类。

编辑:如需进行不区分大小写的排序,请使用以下内容:

boolean isSorted = Ordering.from(String.CASE_INSENSITIVE_ORDER).isOrdered(list);

1
@bestsss没错,但是看了最佳答案后,OP实际上是指String的自然排序。不过我还是会在我的答案中添加一条注释。 - Piotr Findeisen

2
我认为这个需要使用for循环。我会逐个检查每个单词是否按正确的字母顺序排列。最好的情况下,用O(2)时间复杂度来确定列表是否无序,最坏的情况下需要O(n)时间复杂度告诉你列表是有序的。 编辑:上面fge的回答已经提供了所述方法的代码。

我建议使用String类的compareTo()方法来完成此操作。对于像IntegerLongDouble等数字类,它也是同样适用的。在适当的运行时间情况下,这将得到+1的评价。 - Zéychin

1
使用 Collection 类的 sort 方法:
List<String> list = new ArrayList<String>();
//Add Elements
Collections.sort(list);

将指定的列表按其元素的自然顺序升序排序。

0

只需使用循环并检查它们是否按顺序排列:

boolean isSorted = true;
for(int i = 0; i < list.size() - 1; i++) {
   // current String is > than the next one (if there are equal list is still sorted)
   if(list.get(i).compareToIgnoreCase(list.get(i + 1)) > 0) { 
       isSorted = false;
       break;
   }
}

0
ArrayList<String> initial = // smth
ArrayList<String> copy = // copy initial list here
Collections.sort(initial);
return initial.equals(copy);

假设你有一个包含 9,999,999 个字符串的列表,每个字符串都很长,在查看了前几个元素后,你可以判断出它不是简单的 if 循环排序。难道这样会更快吗? ;) - dantuch
这是一个简单的解决方案,但不一定快速。一切取决于您的需求。 - mishadoff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接