如何确定List是否按Java排序?

Eri*_*son 57 java sorting generics wildcard

我想要一个方法,它接受一个实现和返回的List<T>地方,或者取决于列表是否排序.TComparabletruefalse

在Java中实现它的最佳方法是什么?显而易见的是,泛型和通配符意味着能够轻松处理这些事情,但我总是纠缠不清.

有一个类似的方法来检查列表是否是相反的顺序也是很好的.

Col*_*inD 106

Guava通过其令人敬畏的Ordering类提供此功能.一个OrderingComparator++.在这种情况下,如果您有一个实现的类型的列表Comparable,您可以写:

boolean sorted = Ordering.natural().isOrdered(list);
Run Code Online (Sandbox Code Playgroud)

这适用于任何Iterable,而不仅仅是List,您可以null通过指定它们是应该在任何其他非null元素之前还是之后来轻松处理:

Ordering.natural().nullsLast().isOrdered(list);
Run Code Online (Sandbox Code Playgroud)

此外,由于您提到您希望能够检查逆向顺序以及正常顺序,因此可以执行以下操作:

Ordering.natural().reverse().isOrdered(list);
Run Code Online (Sandbox Code Playgroud)

Java 8用户:使用等效的Comparators#isInOrder(Iterable),因为Ordering的其余部分大部分已过时(如类文档中所述).

  • +1用于指向现有代码,以便人们停止重新发明并开始制作新事物. (9认同)
  • 如果你想确保没有重复,还有`isStrictlyOrdered()`. (8认同)
  • @tieTYT:你可以使用`Ordering.from(comparator).isOrdered(list)`; 如果你自己实现了比较器,你可能只是扩展`Ordering`而不是实现`Comparator`开始,在这种情况下它只是`myOrdering.isOrdered(list)`. (3认同)

Sea*_*ean 25

这是一个通用的方法,可以解决这个问题:

public static <T extends Comparable<? super T>>
        boolean isSorted(Iterable<T> iterable) {
    Iterator<T> iter = iterable.iterator();
    if (!iter.hasNext()) {
        return true;
    }
    T t = iter.next();
    while (iter.hasNext()) {
        T t2 = iter.next();
        if (t.compareTo(t2) > 0) {
            return false;
        }
        t = t2;
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*iel 16

简单:

List tmp = new ArrayList(myList);
Collections.sort(tmp);
boolean sorted = tmp.equals(myList);
Run Code Online (Sandbox Code Playgroud)

或者(如果元素具有可比性):

Object prev;
for( Object elem : myList ) {
    if( prev != null && prev.compareTo(elem) > 0 ) {
        return false;
    }
    prev = elem;
}
return true;
Run Code Online (Sandbox Code Playgroud)

或者(如果元素不具有可比性):

Object prev;
for( Object elem : myList ) {
    if( prev != null && myComparator.compare(prev,elem) > 0 ) {
        return false;
    }
    prev = elem;
}
return true;
Run Code Online (Sandbox Code Playgroud)

对于包含空值的列表,实现失败.在这种情况下,您必须添加适当的检查.

  • 我认为你的第一个例子是缺少一行,因为没有填充`tmp`. (3认同)

Pal*_*lle 15

如果您使用的是Java 8,则流可能会有所帮助.

list.stream().sorted().collect(Collectors.toList()).equals(list);
Run Code Online (Sandbox Code Playgroud)

此代码将对列表进行排序,并将其元素收集到另一个列表中,然后将其与初始列表进行比较.如果两个列表在相同位置包含相同的元素,则比较将成功.

此方法可能不是执行速度最快的解决方案,但它是最容易实现的方法,不涉及第三方框架.

  • 比理想的无分配和无排序解决方案有效得多. (3认同)
  • 看起来这与这种情况无关,因为生成的列表永远不会超过语句,因此它永远不会被序列化,变异或从多个线程访问。 (3认同)

Wim*_*uwe 8

如果你需要它进行单元测试,你可以使用AssertJ。它包含一个断言来检查列表是否已排序:

List<String> someStrings = ...
assertThat(someStrings).isSorted();
Run Code Online (Sandbox Code Playgroud)

isSortedAccordingTo如果您想使用自定义比较器进行排序,还有一种替代方法可以使用比较器。


bra*_*boy 5

检查列表或任何数据结构是否只需要O(n)时间.只需使用Iterator界面遍历列表并从头到尾运行数据(在您的情况下,您已经准备好它作为一种可比较的类型),您可以找到它是否已分类或不容易

  • -1因为提问者已经表示他在仿制药和通配符等实施问题上"纠缠不清",我认为这个答案只告诉他已经知道的事情. (4认同)

dig*_*ebs 5

private static <T extends Comparable<? super T>> boolean isSorted(List<T> array){
    for (int i = 0; i < array.size()-1; i++) {
        if(array.get(i).compareTo(array.get(i+1))> 0){
            return false;
        }
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

zzzzz 不确定你们在做什么,但这可以通过简单的 for 循环来完成。