Введение
В этом практическом занятии (лабораторной работе) вы научитесь проверять, отсортирован ли список на Java. Мы рассмотрим различные подходы для выполнения этой задачи, начиная с основного метода сравнения соседних элементов в списке.
Затем вы узнаете, как использовать возможности Java Stream API для более компактного и потенциально более эффективного способа проверки сортировки. Наконец, мы рассмотрим, как обрабатывать разные порядки сортировки, такие как по возрастанию и по убыванию, чтобы сделать ваши проверки сортировки более гибкими.
Сравнение соседних элементов списка
На этом этапе мы научимся сравнивать соседние элементы в списке (точнее, в объекте List на Java). Это распространенная задача, когда вам нужно проверить наличие шаблонов или порядка в последовательности данных. Мы начнем с создания простой Java-программы, которая использует цикл для перебора элементов списка и сравнения каждого элемента с тем, который идет сразу за ним.
Сначала создадим новый Java-файл с именем ListComparison.java в директории ~/project. Вы можете сделать это с помощью проводника файлов WebIDE слева. Щелкните правой кнопкой мыши в области ~/project, выберите "New File" и введите ListComparison.java.
Теперь откройте файл ListComparison.java в редакторе и добавьте следующий код:
import java.util.ArrayList;
import java.util.List;
public class ListComparison {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(3);
numbers.add(2);
numbers.add(4);
numbers.add(5);
System.out.println("Original list: " + numbers);
// Loop through the list, comparing adjacent elements
for (int i = 0; i < numbers.size() - 1; i++) {
Integer currentElement = numbers.get(i);
Integer nextElement = numbers.get(i + 1);
System.out.println("Comparing " + currentElement + " and " + nextElement);
if (currentElement < nextElement) {
System.out.println(currentElement + " is less than " + nextElement);
} else if (currentElement > nextElement) {
System.out.println(currentElement + " is greater than " + nextElement);
} else {
System.out.println(currentElement + " is equal to " + nextElement);
}
}
}
}
Разберем этот код:
import java.util.ArrayList;иimport java.util.List;: Эти строки импортируют необходимые классы для работы со списками на Java.List<Integer> numbers = new ArrayList<>();: Эта строка создает новый список с именемnumbers, который может хранить объекты типаInteger(целые числа).numbers.add(...): Эти строки добавляют элементы в наш список.for (int i = 0; i < numbers.size() - 1; i++): Это циклfor, который перебирает элементы списка. Обратите внимание, что условие цикла -i < numbers.size() - 1. Это важно, потому что мы сравниваемnumbers.get(i)сnumbers.get(i + 1). Если бы мы перебирали доnumbers.size(), на последней итерацииi + 1вышел бы за границы списка.Integer currentElement = numbers.get(i);: Эта строка получает элемент по текущему индексуi.Integer nextElement = numbers.get(i + 1);: Эта строка получает элемент по следующему индексуi + 1.System.out.println(...): Эти строки выводят информацию в консоль, показывая, какие элементы сравниваются и результат сравнения.if,else if,else: Это условные операторы, которые проверяют, является лиcurrentElementменьше, больше или равенnextElement.
Сохраните файл ListComparison.java (Ctrl+S или Cmd+S).
Теперь скомпилируем и запустим программу. Откройте терминал внизу WebIDE. Убедитесь, что вы находитесь в директории ~/project (если нужно, вы можете использовать команду cd ~/project).
Скомпилируйте код с помощью javac:
javac ListComparison.java
Если ошибок нет, будет создан файл ListComparison.class. Теперь запустите скомпилированный код с помощью java:
java ListComparison
Вы должны увидеть вывод, похожий на следующий:
Original list: [1, 3, 2, 4, 5]
Comparing 1 and 3
1 is less than 3
Comparing 3 and 2
3 is greater than 2
Comparing 2 and 4
2 is less than 4
Comparing 4 and 5
4 is less than 5
Этот вывод показывает, что наша программа успешно перебрала элементы списка и сравнила каждую пару соседних элементов, выведя результат каждого сравнения.
Использование Stream API для проверки сортировки
На этом этапе мы рассмотрим более современный и часто более компактный способ проверки, отсортирован ли список, с использованием Stream API Java. Stream API, введенное в Java 8, предоставляет функциональный подход к обработке коллекций данных.
Мы модифицируем нашу предыдущую программу, добавив метод, который будет проверять, отсортирован ли список по возрастанию с использованием потоков (streams).
Откройте файл ListComparison.java в редакторе WebIDE. Добавьте новый метод с именем isSortedAscending в класс ListComparison, вне метода main, но внутри фигурных скобок {} класса ListComparison.
Вот обновленный код для ListComparison.java:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
public class ListComparison {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(3);
numbers.add(2);
numbers.add(4);
numbers.add(5);
System.out.println("Original list: " + numbers);
// Check if the list is sorted using the new method
boolean sorted = isSortedAscending(numbers);
if (sorted) {
System.out.println("The list is sorted in ascending order.");
} else {
System.out.println("The list is NOT sorted in ascending order.");
}
// The previous loop for comparison is removed for simplicity in this step
// but you can keep it if you want to see both methods in action.
}
// Method to check if the list is sorted in ascending order using Streams
public static boolean isSortedAscending(List<Integer> list) {
if (list == null || list.size() <= 1) {
return true; // An empty or single-element list is considered sorted
}
return IntStream.range(0, list.size() - 1)
.allMatch(i -> list.get(i).compareTo(list.get(i + 1)) <= 0);
}
}
Рассмотрим новые части кода:
import java.util.stream.IntStream;: Эта строка импортирует классIntStream, который полезен для работы с последовательностями целых чисел в потоках.public static boolean isSortedAscending(List<Integer> list): Эта строка объявляет новый статический метод с именемisSortedAscending, который принимает список (List) целых чисел (Integer) и возвращает логическое значение (boolean,true, если список отсортирован, иfalseв противном случае).if (list == null || list.size() <= 1): Этот код обрабатывает крайние случаи: пустой список или список с одним элементом всегда считается отсортированным.IntStream.range(0, list.size() - 1): Этот код создает поток целых чисел от 0 до (но не включая)list.size() - 1. Эти целые числа представляют индексы элементов списка, которые мы хотим сравнить..allMatch(i -> list.get(i).compareTo(list.get(i + 1)) <= 0): Это ядро операции с потоком.allMatch()- это терминальная операция, которая проверяет, удовлетворяют ли все элементы потока заданному условию.i -> list.get(i).compareTo(list.get(i + 1)) <= 0- это лямбда-выражение, которое определяет условие. Для каждого индексаiизIntStreamоно получает элемент по индексуiи элемент по индексуi + 1.list.get(i).compareTo(list.get(i + 1))сравнивает два элемента. МетодcompareToвозвращает отрицательное целое число, если первый элемент меньше второго, ноль, если они равны, и положительное целое число, если первый элемент больше второго.<= 0проверяет, является ли результатcompareToменьше или равным нулю. Это условие истинно, если текущий элемент меньше или равен следующему элементу, что соответствует определению сортировки по возрастанию.allMatchвозвращаетtrueтолько в том случае, если это условие истинно для всех соседних пар элементов в списке.
Сохраните файл ListComparison.java.
Теперь скомпилируйте и запустите обновленную программу в терминале:
javac ListComparison.java
java ListComparison
Теперь вывод должен показывать, отсортирован ли список по возрастанию на основе метода isSortedAscending:
Original list: [1, 3, 2, 4, 5]
The list is NOT sorted in ascending order.
Измените список в методе main так, чтобы он был отсортирован, например:
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
numbers.add(5);
Сохраните файл, скомпилируйте и запустите программу снова. Теперь вывод должен быть следующим:
Original list: [1, 2, 3, 4, 5]
The list is sorted in ascending order.
Это демонстрирует, как использовать Stream API для выполнения компактной проверки сортировки по возрастанию.
Обработка различных порядков сортировки
На предыдущем этапе мы создали метод для проверки, отсортирован ли список по возрастанию. На этом этапе мы расширим нашу программу, чтобы она могла обрабатывать различные порядки сортировки: по возрастанию и по убыванию. Мы добавим новый метод, который будет принимать список и желаемый порядок сортировки в качестве входных параметров.
Откройте файл ListComparison.java в редакторе WebIDE. Мы добавим новый метод с именем isSorted, который принимает список и логическое значение (boolean), указывающее, хотим ли мы проверить сортировку по возрастанию (true) или по убыванию (false).
Вот обновленный код для ListComparison.java:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
public class ListComparison {
public static void main(String[] args) {
List<Integer> numbersAsc = new ArrayList<>();
numbersAsc.add(1);
numbersAsc.add(2);
numbersAsc.add(3);
numbersAsc.add(4);
numbersAsc.add(5);
List<Integer> numbersDesc = new ArrayList<>();
numbersDesc.add(5);
numbersDesc.add(4);
numbersDesc.add(3);
numbersDesc.add(2);
numbersDesc.add(1);
List<Integer> numbersUnsorted = new ArrayList<>();
numbersUnsorted.add(1);
numbersUnsorted.add(3);
numbersUnsorted.add(2);
numbersUnsorted.add(4);
numbersUnsorted.add(5);
System.out.println("Checking list: " + numbersAsc);
System.out.println("Is ascending sorted? " + isSorted(numbersAsc, true));
System.out.println("Is descending sorted? " + isSorted(numbersAsc, false));
System.out.println();
System.out.println("Checking list: " + numbersDesc);
System.out.println("Is ascending sorted? " + isSorted(numbersDesc, true));
System.out.println("Is descending sorted? " + isSorted(numbersDesc, false));
System.out.println();
System.out.println("Checking list: " + numbersUnsorted);
System.out.println("Is ascending sorted? " + isSorted(numbersUnsorted, true));
System.out.println("Is descending sorted? " + isSorted(numbersUnsorted, false));
System.out.println();
}
// Method to check if the list is sorted based on the specified order
public static boolean isSorted(List<Integer> list, boolean ascending) {
if (list == null || list.size() <= 1) {
return true; // An empty or single-element list is considered sorted
}
return IntStream.range(0, list.size() - 1)
.allMatch(i -> {
int comparison = list.get(i).compareTo(list.get(i + 1));
if (ascending) {
return comparison <= 0; // For ascending, current must be <= next
} else {
return comparison >= 0; // For descending, current must be >= next
}
});
}
}
Рассмотрим изменения:
- В методе
mainмы создали три разных списка:numbersAsc(отсортированный по возрастанию),numbersDesc(отсортированный по убыванию) иnumbersUnsorted(неотсортированный). - Мы вызываем новый метод
isSortedдля каждого списка, передавая в качестве параметраascendingкакtrue(для проверки сортировки по возрастанию), так иfalse(для проверки сортировки по убыванию). public static boolean isSorted(List<Integer> list, boolean ascending): Это новая сигнатура метода, которая принимает список и логический флаг для указания порядка сортировки.- Внутри лямбда-выражения
allMatch:int comparison = list.get(i).compareTo(list.get(i + 1));: Мы выполняем сравнение соседних элементов.if (ascending): Если флагascendingравенtrue, мы проверяем, чтоcomparison <= 0(текущий элемент меньше или равен следующему).else: Если флагascendingравенfalse(то есть мы проверяем сортировку по убыванию), мы проверяем, чтоcomparison >= 0(текущий элемент больше или равен следующему).
Сохраните файл ListComparison.java.
Теперь скомпилируйте и запустите обновленную программу в терминале:
javac ListComparison.java
java ListComparison
Вывод должен показать результаты проверки каждого списка на сортировку как по возрастанию, так и по убыванию:
Checking list: [1, 2, 3, 4, 5]
Is ascending sorted? true
Is descending sorted? false
Checking list: [5, 4, 3, 2, 1]
Is ascending sorted? false
Is descending sorted? true
Checking list: [1, 3, 2, 4, 5]
Is ascending sorted? false
Is descending sorted? false
Это демонстрирует, как создать гибкий метод с использованием Stream API для проверки различных порядков сортировки, регулируя логику сравнения на основе входного параметра.
Резюме
В этом практическом занятии (lab) мы научились проверять, отсортирован ли список на Java, используя различные подходы. Мы начали с реализации метода для сравнения соседних элементов списка с использованием традиционного цикла, что дает фундаментальное понимание логики проверки сортировки. Это включало перебор элементов списка и сравнение каждого элемента с его последующим элементом для выявления несортированных пар.
Затем мы рассмотрели, как использовать Stream API Java для более компактного и функционального подхода к проверке сортировки списка. Этот метод использует операции с потоками (stream operations), чтобы эффективно определить, находятся ли элементы в желаемом порядке. Наконец, мы рассмотрели обработку различных порядков сортировки (по возрастанию и по убыванию) при выполнении проверки сортировки, показав, как адаптировать логику сравнения для удовлетворения различных требований к сортировке.



