如何在 Java 中检查列表是否已排序

JavaJavaBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在这个实验中,你将学习如何在 Java 中检查一个列表是否已排序。我们将探讨完成此任务的不同方法,首先是比较列表中相邻元素的基本方法。

然后,你将了解如何利用 Java Stream API 的强大功能,以更简洁且可能更高效的方式执行排序检查。最后,我们将介绍如何处理不同的排序顺序,如升序和降序,使你的排序检查更加灵活。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/DataStructuresGroup(["Data Structures"]) java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java(("Java")) -.-> java/FileandIOManagementGroup(["File and I/O Management"]) java(("Java")) -.-> java/BasicSyntaxGroup(["Basic Syntax"]) java/BasicSyntaxGroup -.-> java/for_loop("For Loop") java/DataStructuresGroup -.-> java/arrays("Arrays") java/DataStructuresGroup -.-> java/sorting("Sorting") java/DataStructuresGroup -.-> java/collections_methods("Collections Methods") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/arraylist("ArrayList") java/FileandIOManagementGroup -.-> java/stream("Stream") subgraph Lab Skills java/for_loop -.-> lab-559950{{"如何在 Java 中检查列表是否已排序"}} java/arrays -.-> lab-559950{{"如何在 Java 中检查列表是否已排序"}} java/sorting -.-> lab-559950{{"如何在 Java 中检查列表是否已排序"}} java/collections_methods -.-> lab-559950{{"如何在 Java 中检查列表是否已排序"}} java/arraylist -.-> lab-559950{{"如何在 Java 中检查列表是否已排序"}} java/stream -.-> lab-559950{{"如何在 Java 中检查列表是否已排序"}} end

比较列表中的相邻元素

在这一步中,你将学习如何比较列表(更具体地说,是 Java 中的 List)中的相邻元素。当你需要检查数据序列中的模式或顺序时,这是一项常见的任务。我们将从创建一个简单的 Java 程序开始,该程序使用循环遍历列表,并将每个元素与其紧随其后的元素进行比较。

首先,在你的 ~/project 目录中创建一个名为 ListComparison.java 的新 Java 文件。你可以使用左侧 WebIDE 的文件资源管理器来完成此操作。在 ~/project 区域内右键单击,选择“新建文件”,然后输入 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(...):这些代码行将信息打印到控制台,显示正在比较的元素以及比较结果。
  • ifelse ifelse:这些是条件语句,用于检查 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 进行排序检查

在这一步中,我们将探索一种更现代且通常更简洁的方法,即使用 Java 的 Stream API 来检查列表是否已排序。Stream API 是 Java 8 引入的,它为处理数据集合提供了一种函数式编程的方式。

我们将修改之前的程序,添加一个使用流来检查列表是否按升序排序的方法。

在 WebIDE 编辑器中打开 ListComparison.java 文件。在 ListComparison 类中,main 方法之外但在 ListComparison 类的花括号 {} 内添加一个名为 isSortedAscending 的新方法。

以下是更新后的 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 的新静态方法,该方法接受一个 Integer 类型的 List 作为参数,并返回一个 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 是一个 lambda 表达式,用于定义条件。对于 IntStream 中的每个索引 i,它会获取索引 i 处的元素和索引 i + 1 处的元素。
    • list.get(i).compareTo(list.get(i + 1)) 用于比较这两个元素。compareTo 方法在第一个元素小于第二个元素时返回一个负整数,在两个元素相等时返回 0,在第一个元素大于第二个元素时返回一个正整数。
    • <= 0 用于检查 compareTo 方法的结果是否小于或等于 0。如果当前元素小于或等于下一个元素,这个条件就为 true,这正是升序的定义。
    • 只有当列表中所有相邻元素对都满足这个条件时,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 简洁地检查列表是否按升序排序。

处理不同的排序顺序

在上一步中,我们创建了一个方法来检查列表是否按 升序 排序。在这一步,我们将扩展程序以处理不同的排序顺序:升序和降序。我们将添加一个新方法,该方法将列表和所需的排序顺序作为输入。

在 WebIDE 编辑器中打开 ListComparison.java 文件。我们将添加一个名为 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 方法,并且分别传入 true(检查升序)和 false(检查降序)作为 ascending 参数。
  • public static boolean isSorted(List<Integer> list, boolean ascending):这是我们新方法的签名,接受列表和一个表示排序顺序的布尔标志。
  • allMatch 的 lambda 表达式内部:
    • 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 创建一个灵活的方法,通过根据输入参数调整比较逻辑来检查不同的排序顺序。

总结

在本次实验中,我们学习了如何使用不同的方法来检查 Java 中的列表是否已排序。首先,我们实现了一个使用传统循环来比较列表中相邻元素的方法,这让我们对排序检查逻辑有了基本的理解。该方法需要遍历列表,并将每个元素与其后续元素进行比较,以找出任何未排序的元素对。

随后,我们探索了如何利用 Java Stream API 以更简洁和函数式的方式来检查列表的排序状态。这种方法利用流操作来高效地确定元素是否按所需顺序排列。最后,我们讨论了在进行排序检查时如何处理不同的排序顺序(升序和降序),展示了如何调整比较逻辑以满足各种排序需求。