素敵なサムシングを独断と偏見で一方的に紹介するブログ(´・ω・`)

IT

【Java8 Stream】ListをMapにした際に並び順が保証されない【LinkedHashMap】

投稿日: 2019年10月7日
最終更新日:

スポンサーリンク

336×280




Listの順番を担保したMapを作りたい

ソートされたListからMapを作ると順序が変わる

Java8以降でstreamAPIを使い、ListオブジェクトからMapオブジェクトを生成したいというケースは良くあると思います。

今回の例ではとてもシンプルなListオブジェクトですが、実際にはModelなどをListの要素として持つ形になると思います。

そんな時に、すでにソートされたList(DBからの取得結果etc…)をstreamで回してMapオブジェクトにしようとする際に以下のような書き方をする場合が多いと思います。

しかし、この実装方法で作成したMapからkeySet()を呼び出してをさらにstreamでループ処理しようとした際に、List順序が担保されないMapオブジェクトが生成されてしまいます。

原因

toMapを使う場合、引数にMapクラスを何も指定しないとHashMapクラスで生成されます。

そしてご存知の通りHashMapクラスは要素の一意性をkeyのハッシュ値で管理するので元々順序を保証してくれません

勘違いしやすいケース

以下のようなとてもシンプルなListの場合はぱっと見順序を保持していそうですが、たまたまハッシュ値と順序が一緒なだけなので、要素がオブジェクトになった途端順序がバラバラになってしまいます。

試しにリストをハッシュとは逆順にすると、、、、

はい残念。

解決方法

なので、

ではなく、

を使い、第四引数にてLinkedHashMapクラスを渡し、明示的に使用するMapクラス指定することで解決が可能となります。

ちなみに、LinkedHashMapクラスとは追加した順番を保持してくれる便利なMapクラスとなっています。

今回は実際にこちらを使って追加した順番を担保するサンプルを作ってみようと思います。

手順

collect関数の引数を修正

修正方法はとても簡単です。

以下のようにCollectors.toMap第三引数第四引数を以下のように追加するだけでOKです。

確認

実行すると以下のような形になると思います。

完璧ですね♪

TreeMapでは怪しい

LinkedHashMapではなく、TreeMapでもいけるという記事をいくつか見ましたので確かめてみました、。

むむっ。

TreeMapクラスは通常のHashMapクラスと同様にハッシュによる順序に自動ソートされるのでうまくいきませんでした。

しかし、引数を渡さないtoMapと同様に、Listの値によってはうまく順序を保っているように見えてしまうので注意が必要です。

本日のオススメ商品

終わりに

以上のように簡単にList要素の順番に担保されたMapオブジェクトを生成することが可能になりました。

お困りの方は、こちらのやり方を参考にしてみてください♪

336×280




336×280




CATEGORIES & TAGS

IT, , , , , , , , ,

blogenist

Author: blogenist