JavaでSetをListに変換する方法
Javaのリストはデータの順序付きのコレクションであり、セットはデータの順序なしのコレクションです。リストは重複したエントリーを持つことができますが、セットはできません。両データ構造は異なるシナリオで有用です。
セットをリストに変換する方法を知っていることは便利です。これにより、順序のないデータを順序付けられたデータに変換することができます。
セットの初期化
集合を初期化し、いくつかの要素を追加しましょう。
import java.util.*;
public class Main {
public static void main(String[] args)
{
Set<Integer> a = new HashSet<>();
a.add(1);
a.add(2);
a.add(3);
a.add(1);
System.out.println(a);
}
}

HashSetのadd()メソッドは、要素をセットに追加します。要素は重複しないことに注意してください。セットは順序なしのため、挿入順に要素を取得する方法はありません。
JavaでSetをListに変換する方法を教えてください。
集合をリストに変換しましょう。変換する方法は複数あります。それぞれの方法は他と異なり、その違いは微妙です。
1. Set引数を持つリストコンストラクタ
セットをリストに変換する最も直接的な方法は、リストを作成する際に引数としてセットを渡すことです。これにより、コンストラクタが呼び出され、そこから以降はコンストラクタが残りの処理を担当します。
import java.util.*;
public class Main {
public static void main(String[] args)
{
Set<Integer> a = new HashSet<>();
a.add(1);
a.add(2);
a.add(3);
a.add(1);
List<Integer> arr = new ArrayList<>(a);
System.out.println(arr);
System.out.println(arr.get(1));
}
}

セットがリストに変換されたので、要素は現在順序が付いています。そのため、要素にインデックスでアクセスするためにget()メソッドを使えます。
2. 伝統的なforループを使用している。
私たちは、セットからリストへ要素を明示的にコピーするために、古くからあるforループを使用することができます。
import java.util.*;
public class Main {
public static void main(String[] args)
{
Set<Integer> a = new HashSet<>();
a.add(1);
a.add(2);
a.add(3);
a.add(1);
List<Integer> arr = new ArrayList<>(a);
for (int i : a)
arr.add(i);
System.out.println(arr);
System.out.println(arr.get(1));
}
}

forループはセットの要素を一つずつ取り出し、リストに要素を追加します。
3. リストのaddAll()メソッド
リストには、addAll()というメソッドがあります。このメソッドは複数の値を一度にリストに追加することができます。おそらく、この操作は2つのリストを結合する際に使用されることを思い出すかもしれません。addAll()はまた、セットの要素をリストに追加するためにも使用できます。
import java.util.*;
public class Main {
public static void main(String[] args)
{
Set<Integer> a = new HashSet<>();
a.add(1);
a.add(2);
a.add(3);
a.add(1);
List<Integer> arr = new ArrayList<>();
arr.addAll(a);
System.out.println(arr);
System.out.println(arr.get(1));
}
}

4. Stream APIのcollect()メソッド
Java8以降から、Stream.collect()が利用可能です。ToListコレクターは、すべてのStream要素をListインスタンスに収集します。
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args)
{
Set<Integer> a = new HashSet<>();
a.add(1);
a.add(2);
a.add(3);
a.add(1);
List<Integer> arr;
arr = a.stream().collect(Collectors.toList());
System.out.println(arr);
System.out.println(arr.get(1));
}
}

stream.collect()のドキュメントには、返されるリストの種類、可変性、直列性、スレッドセーフ性についての保証はないと記載されています。返されるリストに対してより多くの制御が必要な場合は、toCollection(Supplier)を使用してください。
リストのタイプを指定するには、toCollection(ArrayList::new)を使用します。
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args)
{
Set<Integer> a = new HashSet<>();
a.add(1);
a.add(2);
a.add(3);
a.add(1);
List<Integer> arr;
arr = a.stream().collect(Collectors.toCollection(ArrayList::new));
System.out.println(arr);
System.out.println(arr.get(1));
}
}
おすすめの読み物:Javaにおけるストリーム
5. List.copyOf() メソッド
Java 10以降のListには、copyOf()メソッドがあります。このメソッドは、与えられたコレクションの要素を保持した、変更不可能なリストをイテレーション順序で返します。このリストには、nullの要素は含まれません。もしもセットにnullが含まれている場合、このメソッドはヌルポインタ例外を返します。
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args)
{
Set<Integer> a = new HashSet<>();
a.add(1);
a.add(2);
a.add(3);
a.add(1);
List<Integer> arr;
arr = List.copyOf(a);
System.out.println(arr);
System.out.println(arr.get(1));
}
}

セットにnullを追加し、リストに変換してみる。
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args)
{
Set<Integer> a = new HashSet<>();
a.add(1);
a.add(2);
a.add(3);
a.add(1);
a.add(null);
List<Integer> arr;
arr = List.copyOf(a);
System.out.println(arr);
System.out.println(arr.get(1));
}
}

もしも変更不可能なリストに要素を追加しようとすると、以下のようなエラーが表示されます。

null要素を含むセットをリストに変換するために、addAll()メソッドを使用する。
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args)
{
Set<Integer> a = new HashSet<>();
a.add(1);
a.add(2);
a.add(3);
a.add(1);
a.add(null);
List<Integer> arr = new ArrayList<>();
arr.addAll(a);
// arr = List.copyOf(a);
System.out.println(arr);
System.out.println(arr.get(1));
}
}

リストの最初にnullが表示されることに注意してください。
結論
私たちは、セットをリストに変換するための非常に興味深い方法をいくつか見ました。それぞれの方法で作成されるリストのタイプに注意することが重要です。例えば、copyOf()メソッドは不変なリストを生成し、null要素を扱うことができません。一方、stream.collect()メソッドは何も保証しません。コンストラクタとaddAll()メソッドは、中でも最も信頼性があります。