1. 概要

List は、Javaで非常に一般的に使用されるデータ構造です。 場合によっては、ネストが必要になることがありますリスト次のようないくつかの要件の構造リスト >>

このチュートリアルでは、この「リストのリスト」データ構造を詳しく見て、日常の操作について説明します。

2. リスト配列と リストのリスト

「リストのリスト」データ構造を2次元マトリックスとして見ることができます。 したがって、いくつかのグループを作成する場合リストオブジェクトには、2つのオプションがあります。

  • アレイベース: リスト []
  • リストベース: リスト >>

次に、いつどれを選択するかを見てみましょう。

配列は、O(1)時間で実行される「get」および「set」操作に対して高速です。 ただし、配列の長さは固定されているため、要素を挿入または削除するために配列のサイズを変更するのはコストがかかります

一方、リストは、O(1)時間で実行される挿入および削除操作に対してより柔軟です。 一般的に、 List は、「get/set」操作でArrayよりも低速です。 ただし、ArrayListなどの一部のList実装は、内部的に配列に基づいています。 したがって、通常、「get/set」操作でのArrayArrayListのパフォーマンスの違いは目立ちません。

したがって、 リストを選びます >ほとんどの場合、柔軟性を高めるためのデータ構造

もちろん、パフォーマンスが重要なアプリケーションで作業していて、最初のディメンションのサイズを変更しない場合、たとえば、内部を追加または削除することはありません。 リスト –使用を検討できますリスト [] 構造。

主に話し合いますリスト >> このチュートリアルでは。

3. リストリストの一般的な操作

それでは、日常の操作について見ていきましょう。 リスト >>

簡単にするために、 リスト >> ユニットテストメソッドでオブジェクトを作成し、結果を確認します。

さらに、変更を簡単に確認するために、リストリストのコンテンツを出力するメソッドも作成しましょう。

private void printListOfLists(List<List<String>> listOfLists) {
    System.out.println("\n           List of Lists          ");
    System.out.println("-------------------------------------");
    listOfLists.forEach(innerList -> {
        String line = String.join(", ", innerList);
        System.out.println(line);
    });
}

次に、最初にリストのリストを初期化します。

3.1. リストのリストを初期化する

CSVファイルからデータをインポートしますリスト >> 物体。 まず、CSVファイルの内容を見てみましょう。

Linux, Microsoft Windows, Mac OS, Delete Me
Kotlin, Delete Me, Java, Python
Delete Me, Mercurial, Git, Subversion

ファイルにexample.csvという名前を付け、 resources /listoflistsディレクトリに配置するとします。

次に、メソッドを作成しましょうファイルを読むデータをに保存しますリスト >> 物体:

private List<List<String>> getListOfListsFromCsv() throws URISyntaxException, IOException {
    List<String> lines = Files.readAllLines(Paths.get(getClass().getResource("/listoflists/example.csv")
        .toURI()));

    List<List<String>> listOfLists = new ArrayList<>();
    lines.forEach(line -> {
        List<String> innerList = new ArrayList<>(Arrays.asList(line.split(", ")));
        listOfLists.add(innerList);
    });
    return listOfLists;
}

の中に getListOfListsFromCsv メソッドでは、最初にCSVファイルからすべての行を読み取りますリスト物体。 次に、 行リスト各行を変換します( ) の中へリスト

最後に、変換されたすべてのものを追加しますリストに反対する listOfLists 。 したがって、リストのリストを初期化しました。

好奇心旺盛な目が私たちが包むことを検出したかもしれません Arrays.asList(..) 新しいで ArrayList <>() 。 これは、Arrays.asListメソッドが不変のListを作成するためです。 ただし、後で内部リストにいくつかの変更を加えます。 したがって、新しいArrayListオブジェクトでラップします。

リストオブジェクトのリストが正しく作成されている場合、外側のリストには、CSVファイルの行数である3つの要素が含まれているはずです。

さらに、各要素は内部リストであり、各要素には4つの要素が含まれている必要があります。 次に、これを検証するための単体テストメソッドを記述しましょう。 また、初期化されたリストのリストを出力します。

List<List<String>> listOfLists = getListOfListsFromCsv();

assertThat(listOfLists).hasSize(3);
assertThat(listOfLists.stream()
  .map(List::size)
  .collect(Collectors.toSet())).hasSize(1)
  .containsExactly(4);

printListOfLists(listOfLists);

メソッドを実行すると、テストに合格し、次の出力が生成されます。

           List of Lists           
-------------------------------------
Linux, Microsoft Windows, Mac OS, Delete Me
Kotlin, Delete Me, Java, Python
Delete Me, Mercurial, Git, Subversion

次に、listOfListsオブジェクトにいくつかの変更を加えましょう。 しかし、最初に、外側のリストに変更を適用する方法を見てみましょう。

3.2. アウターリストへの変更の適用

外側のリストに注目すると、最初は内側のリストを無視できます。 言い換えると、 リストを見ることができます >通常のリストとして 。

したがって、通常のListオブジェクトを変更することは困難ではありません。 addremoveなどのListのメソッドを呼び出して、データを操作できます。

次に、外側のリストに新しい要素を追加しましょう。

List<List<String>> listOfLists = getListOfListsFromCsv();
List<String> newList = new ArrayList<>(Arrays.asList("Slack", "Zoom", "Microsoft Teams", "Telegram"));
listOfLists.add(2, newList);

assertThat(listOfLists).hasSize(4);
assertThat(listOfLists.get(2)).containsExactly("Slack", "Zoom", "Microsoft Teams", "Telegram");

printListOfLists(listOfLists);

外側のリストの要素は実際にはリスト物体。 上記の方法が示すように、人気のあるオンライン通信ユーティリティのリストを作成します。 次に、新しいリストをlistOfListsindex=2の位置に追加します。

ここでも、アサーションの後に、listOfListsのコンテンツを出力します。

           List of Lists           
-------------------------------------
Linux, Microsoft Windows, Mac OS, Delete Me
Kotlin, Delete Me, Java, Python
Slack, Zoom, Microsoft Teams, Telegram
Delete Me, Mercurial, Git, Subversion

3.3. 内部リストへの変更の適用

最後に、内部リストを操作する方法を見てみましょう。

listOfListはネストされたList構造であるため、最初に変更する内部リストオブジェクトに移動する必要があります。 インデックスが正確にわかっている場合は、getメソッドを使用するだけです。

List<String> innerList = listOfLists.get(x);
// innerList.add(), remove() ....

ただし、すべての内部リストに変更を適用する場合は、ループまたは StreamAPIを介してリストオブジェクトのリストを渡すことができます。

次に、listOfListsオブジェクトからすべての「DeleteMe」エントリを削除する例を見てみましょう。

List<List<String>> listOfLists = getListOfListsFromCsv();

listOfLists.forEach(innerList -> innerList.remove("Delete Me"));

assertThat(listOfLists.stream()
    .map(List::size)
    .collect(Collectors.toSet())).hasSize(1)
    .containsExactly(3);

printListOfLists(listOfLists);

上記のメソッドで見たように、 listOfLists.forEach{…}を介して各内部リストを反復処理し、ラムダ式を使用してから「DeleteMe」エントリを削除します。 innerList

テストを実行すると、合格して次の出力が生成されます。

           List of Lists           
-------------------------------------
Linux, Microsoft Windows, Mac OS
Kotlin, Java, Python
Mercurial, Git, Subversion

4. 結論

この記事では、リストのデータ構造のリストについて説明しました。

さらに、例を通じてリストのリストにある一般的な操作について説明しました。

いつものように、この記事の完全なコードはGitHubにあります。