Java でリストがソートされているかどうかを確認する方法

JavaJavaBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、Java でリストがソートされているかどうかを確認する方法を学びます。このタスクを達成するためのさまざまなアプローチを探ります。まずは、リスト内の隣接する要素を比較する基本的な方法から始めます。

次に、Java Stream API の機能を活用して、より簡潔で潜在的に効率的な方法でソートの確認を行う方法を学びます。最後に、昇順や降順などの異なるソート順を扱う方法について説明し、ソートの確認をより汎用的に行えるようにします。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/BasicSyntaxGroup(["Basic Syntax"]) 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/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<>();:これは、Integer(整数)オブジェクトを保持できる numbers という名前の新しいリストを作成します。
  • 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:これらは、currentElementnextElement より小さい、大きい、または等しいかをチェックする条件文です。

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 を使用してリストがソートされているかどうかを確認する、より最新で簡潔な方法を探ります。Java 8 で導入された Stream API は、データのコレクションを処理するための関数型アプローチを提供します。

前のプログラムを変更して、ストリームを使用してリストが昇順でソートされているかどうかを確認するメソッドを追加します。

WebIDE のエディターで ListComparison.java ファイルを開きます。ListComparison クラスに isSortedAscending という新しいメソッドを追加します。このメソッドは 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 という新しい静的メソッドを宣言します。このメソッドは IntegerList を引数に取り、boolean を返します(ソートされている場合は true、そうでない場合は false)。
  • if (list == null || list.size() <= 1):これはエッジケースを処理します。空のリストまたは要素が 1 つのリストは常にソートされていると見なされます。
  • IntStream.range(0, list.size() - 1):これは 0 から list.size() - 1 まで(ただし、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 は、条件を定義するラムダ式です。IntStream の各インデックス i に対して、インデックス i の要素とインデックス i + 1 の要素を取得します。
    • list.get(i).compareTo(list.get(i + 1)) は 2 つの要素を比較します。compareTo は、最初の要素が 2 番目の要素より小さい場合は負の整数を返し、等しい場合は 0 を返し、最初の要素が 2 番目の要素より大きい場合は正の整数を返します。
    • <= 0 は、compareTo の結果が 0 以下であるかどうかをチェックします。この条件は、現在の要素が次の要素以下である場合に true となり、これが昇順の定義です。
    • allMatch は、リスト内のすべての隣接するペアに対してこの条件が true である場合にのみ 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 ファイルを開きます。リストと、昇順(true)または降順(false)を確認するかを示す boolean 値を引数に取る isSorted という新しいメソッドを追加します。

以下は 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 メソッドで 3 つの異なるリストを作成しました。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 を使用して、入力パラメータに基づいて比較ロジックを調整することで、異なるソート順を確認する柔軟なメソッドを作成する方法を示しています。

まとめ

この実験では、Java でリストがソートされているかどうかを異なるアプローチで確認する方法を学びました。まず、従来のループを使用してリスト内の隣接する要素を比較するメソッドを実装しました。これにより、ソートの確認ロジックの基本的な理解が得られます。具体的には、リストを反復処理し、各要素をその後続要素と比較して、ソートされていないペアを特定します。

その後、Java Stream API を活用して、リストのソート状態をより簡潔で関数型のアプローチで確認する方法を探りました。この方法では、ストリーム操作を利用して、要素が目的の順序に並んでいるかを効率的に判断します。最後に、ソートの確認を行う際に異なるソート順(昇順と降順)を扱う方法を取り上げ、様々なソート要件に対応するために比較ロジックを調整する方法を示しました。