如何确定列表是否在Java中sorting?
我想要一个方法,接受一个List<T>
其中T
实现Comparable
并根据列表是否sorting返回true
或false
。
在Java中实现这个最好的方法是什么? generics和通配符很容易处理这些事情,但是我现在都陷入了困境。
有一个类似的方法来检查列表是否相反,也是很好的。
Guava通过它的令人敬畏的Ordering类提供这个function。 Ordering
是一个Comparator
++。 在这种情况下,如果你有一个实现了Comparable
types的列表,你可以这样写:
boolean sorted = Ordering.natural().isOrdered(list);
这适用于任何Iterable
,而不仅仅是List
,并且您可以通过指定它们是否应该在任何其他非null
元素之前或之后轻松地处理null
:
Ordering.natural().nullsLast().isOrdered(list);
另外,既然你提到你希望能够像正常一样检查反向顺序,那么可以这样做:
Ordering.natural().reverse().isOrdered(list);
Java 8用户 :使用等效的Comparators#isInOrder(Iterable)
来代替,因为Ordering的其余部分大部分已经过时(正如类文档中所解释的)。
这是一个通用的方法,可以做到这一点:
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; }
简单:
List tmp = new ArrayList(myList); Collections.sort(tmp); boolean sorted = tmp.equals(myList);
或者(如果要素可比):
Object prev; for( Object elem : myList ) { if( prev != null && prev.compareTo(elem) > 0 ) { return false; } prev = elem; } return true;
或者(如果要素不可比):
Object prev; for( Object elem : myList ) { if( prev != null && myComparator.compare(prev,elem) > 0 ) { return false; } prev = elem; } return true;
包含空值的列表的实现失败。 在这种情况下,您必须添加适当的检查。
如果您正在使用Java 8,则stream可能会提供帮助。
list.stream().sorted().collect(Collectors.toList()).equals(list);
这段代码会将列表sorting,并将其元素收集到另一个列表中,然后将其与初始列表进行比较。 如果两个列表在相同的位置包含相同的元素,则比较将是成功的。
这种方法可能不是性能最快的解决scheme,但它是最容易实现的解决scheme,不涉及第三方框架。
检查一个列表或任何数据结构是否是一个只需要O(n)个时间的任务。 只需使用Iterator
接口迭代列表,并Iterator
遍历数据(在您的情况下,您已经准备好了它作为一种types的Comparable),您可以查找它是否已sorting或不容易
只需使用迭代器查看List<T>
。
public static <T extends Comparable> boolean isSorted(List<T> listOfT) { T previous = null; for (T t: listOfT) { if (previous != null && t.compareTo(previous) < 0) return false; previous = t; } return true; }
这是我会做的:
public static <T extends Comparable<? super T>> boolean isSorted(List<T> list) { if (list.size() != 0) { ListIterator<T> it = list.listIterator(); for (T item = it.next(); it.hasNext(); item = it.next()) { if (it.hasPrevious() && it.previous().compareTo(it.next()) > 0) { return false; } } } return true; }
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; }
zzzzz不知道你们在做什么,但是这可以在简单的循环中完成。
这是一个需要O(n)个时间(最糟糕的情况)的操作。 您需要处理两种情况:列表按降序排列,列表按升序sorting。
您将需要将每个元素与下一个元素进行比较,同时确保订单被保留。
数组上的一个简单的实现:
public static <T extends Comparable<? super T>> boolean isSorted(T[] a, int start, int end) { while (start<end) { if (a[start].compareTo(a[start+1])>0) return false; start++; } return true; }
转换列表:
public static <T extends Comparable<? super T>> boolean isSorted(List<T> a) { int length=a.size(); if (length<=1) return true; int i=1; T previous=a.get(0); while (i<length) { T current=a.get(i++); if (previous.compareTo(current)>0) return false; previous=current; } return true; }
如果你需要unit testing,你可以使用AssertJ 。 它包含一个断言来检查List是否被sorting:
List<String> someStrings = ... assertThat(someStrings).isSorted();
还有一种替代方法isSortedAccordingTo
,如果您想使用自定义比较器进行sorting,则需要比较器。