【エンジニア初心者必見】<Java8>Collectionの相互変換まとめ
さばみそ君、Javaの勉強をしてるんだけど、Collectionsクラスの変換がよくわからないんだ
なるほどね!マイケル君じゃあ、Collectionsクラスの変換方法をまとめておくから、これを勉強しておくといいよ
こんにちは。どうもさばみそです!
今回は、プログラミングを独学で学ばれている方やプログラミング初心者で将来プログラマーになりたいという方のために、JavaのCollectionsクラスの変換方法をまとめたいと思います。
※自分のための備忘としても書いています。。。笑
Collectionとは
まずCollectionとは、公式ドキュメントによるとこう書かれています
コレクション階層のルート・インタフェースです。コレクションは、その要素であるオブジェクトのグループを表します。コレクションによっては要素の重複を許可しますが、許可しないコレクションもあります。また、順序付けられているコレクションとそうでないコレクションがあります。
ふむふむ。。なるほど。。なんのこっちゃって感じですよね
まあ、簡単に説明するとCollection(コレクション)は、ListやSet、Mapなどが継承している大元のインターフェースであるとことです。
そして、Collectionを継承しているのは、以下のものになります。
- Set
- List
- Map
- Arrays
- HashSet
全てを列挙すると多くなってしまうので、今回は代表的なものだけをあげてます。 詳しく知りたい人は、下記の公式リファレンスを見てみるとわかりやすいです
ちなみに、よく使われるHashMapは、Collectionを継承しているわけではなく、実は直接、Objectを継承しているのでパッケージが違います。
配列からリストへの変換
ではまず、配列からリストへの変換を行いたいと思います。
String[] stringArray = { "あ", "いい", "うぅ", "エー", "オウフ" };
このような配列があった場合、変換に使うものは、ArraysクラスのasListメソッドです
asListとは、指定された配列に連動する固定サイズのリストを返します。
List<String> stringList = Arrays.asList(stringArray);
このようになります。
配列からリストへは、この1パターンしかありませんので、簡単ですね!
リストから配列への変換
では、逆にリストを配列に変換したい場合は、どうすれば良いでしょうか?
List<String> strings = Arrays.asList("あ", "いい", "うぅ", "エー", "オウフ");
それは、ListクラスのtoArrayメソッドです。
toArrayとは、このリスト内のすべての要素を適切な順序で(最初の要素から最後の要素へ)含んでいる配列を返します。返される配列の実行時の型は、指定された配列の型になります。
では、変換方法はこのようになります
String[] stringArray = strings.toArray(new String[0]);
リストからセットへの変換
どんどん行きましょう! 次は、リストからセットへの変換です
List<String> strings = Arrays.asList("あ", "いい", "うぅ", "エー", "オウフ");
今回は、今までとは変換の方法が異なります! セットへの変換は、HashSetクラスを使います!
HashSetクラスとは、このクラスは、ハッシュ表(実際にはHashMapのインスタンス)に連動し、Setインタフェースを実装します。このクラスでは、セットの反復順序について保証しません。特に、その順序を一定に保つことを保証しません。このクラスは、null要素を許容します。
簡単にいうと、HashSetクラスとは、Setを生成するためにあるクラスだということです
そのHashSetクラスのコンストラクタにHashSet(Collection<? extends E> c)というものが用意されており、引数にCollectionの要素を渡すとそれを使って、Setを生成してくれるのです!
HashSet<String> stringSet = new HashSet<>(strings);
セットからリストへの変換
次は、反対にセットからリストへ変換を行って見ましょう
まずは、このようなセットを用意しておきます
Set<String> strings = new HashSet<String>() {{ add("あ"); add("いい"); add("うぅ"); add("エー"); add("オウフ"); }};
これをリストへ変換する際に使うのは、ArrayListクラスのコンストラクタです
リストからセットへ変換したのと同じく、ArrayListクラスのコンストラクタには、ArrayList(Collection<? extends E> c)というのが用意されており、それを使いリストを生成することで、SetクラスをListクラスへ変換することができます
ArrayList(Collection<? extends E> c)とは、 指定されたコレクションの要素が含まれているリストを、要素がコレクションのイテレータによって返される順序で作成します
ということで、変換方法は、このようになります
List<String> stringList = new ArrayList<>(strings);
リストからマップへの変換
最後に、少し難しいリストからマップへの変換方法を教えたいと思います。
特に、Java8のStream APIを活用した方法となるので、Java8以前の使われている方とは方法が異なるので注意してください。
では、まずList要素を準備します
class Dto { final long id; final String val; Dto(long id, String val) { this.id = id; this.val = val; } @Override public String toString() { return String.format("Dto(%d, %s)", id, val); } } List<Dto> dtos = IntStream.rangeClosed(1, 10).mapToObj(id -> new Dto(id, UUID.randomUUID().toString())).collect(Collectors.toList());
今までと違い少し特殊な物を用意しているので、要素を解説を挟みますね
このList要素は、1から10の要素番号に、ランダムな値を格納するといった内容になります。
Dto[1] = 34551912-f2be-4896-9a8e-999367c01e93 Dto[2] = d68017ba-a7e3-41d1-9e35-876b72748282) …
このように、生成される中身が10個あると思ってください。
では、それを1から10(要素番号)をKey(キー)とした、value(バリュー)に中身が格納されているMap形式へ変換したいと思います
ListからMapへ変換する際には、StreamAPIのラムダ式を書くことで、手軽に変換することができます。
説明するより、見てもらった方が早いと思いますので、こちらになります
Map<Long, Dto> map = dtos.stream() .collect(Collectors.toMap( s -> s.id, s -> s ));
処理の流れとしては、
- Listをstreamにし、
- streamからListをCollectorに渡す
- toMapメソッドを使いMapへ変換する
- その際に、キーを要素番号として値をそれに紐づく値を指定
のように変換することができます。
まとめ
- Collectionには、MapやList,Arrayなどがある
- 配列からリストへは、asListメソッドを使う
- リストから配列には、toArrayメソッドを使う
- リストからセットは、HashSetコンストラクタを使う
- セットからリストは、ArrayListコンストラクタを使う
- リストからマップは、toMapメソッドを使い、ラムダ式で書くとコードがスッキリする
どうだったでしょうか?
今回は、Java8を使ったCollectionの変換方法をまとめてみました
実務でもよく使われる書き方で書いているので、ご参考になればと思います。
また、変換方法はこれ以外にもあるので、公式ドキュメントを見るなりして、調べてみるといいと思います。
皆さんの気になる話題や、書いて欲しい話題などをコメントに書いていただくと記事作成の大きな手助けとなります。
皆さんのコメントお待ちしております