Я хотел бы метод, который берет a List<T>
где T
реализации Comparable
и возвраты true
или false
в зависимости от того, отсортирован ли список или нет.
Что лучший способ состоит в том, чтобы реализовать это в Java? Очевидно, что дженерики и подстановочные знаки предназначены, чтобы смочь обработать такие вещи легко, но я получаю все запутанные.
Также было бы хорошо иметь аналогичный метод, чтобы проверить, в обратном порядке ли список.
Используя Java 8 потоков:
boolean isSorted = IntStream.range(1, list.size())
.map(index -> list.get(index - 1).compareTo(list.get(index)))
.allMatch(order -> order <= 0);
Это также работает на пустые списки. Это однако только эффективно для списков, которые также реализуют RandomAccess
интерфейс маркера (например, ArrayList
).
, Если у Вас нет доступа к базовому набору потока, следующий ужасный взлом может использоваться:
Stream<T> stream = ...
Comparator<? super T> comparator = ...
boolean isSorted = new AtomicInteger(0) {{
stream.sequential()
.reduce((left, right) -> {
getAndUpdate(order -> (order <= 0) ? comparator.compare(left, right) : order);
return right;
});
}}.get() <= 0;
Здесь прибывает метод с помощью Iterable
и Comparator
.
<T> boolean isSorted(Iterable<? extends T> iterable,
Comparator<? super T> comparator) {
boolean beforeFirst = true;
T previous = null;
for (final T current : iterable) {
if (beforeFirst) {
beforeFirst = false;
previous = current;
continue;
}
if (comparator.compare(previous, current) > 0) {
return false;
}
previous = current;
}
return true;
}
И метод для Iterable
из Comparable
и флаг для упорядочивания.
<T extends Comparable<? super T>> boolean isSorted(
Iterable<? extends T> iterable, boolean natural) {
return isSorted(iterable, natural ? naturalOrder() : reverseOrder());
}