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

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

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

YouTubeも見てね♪

Anker PowerCor

created by Rinker
Anker
¥4,990 (2024/03/15 15:06:44時点 Amazon調べ-詳細)

旅行には必須の大容量モバイルバッテリー!

【最新機種】GoPro hero11 Black

created by Rinker
GoPro(ゴープロ)
¥62,000 (2024/03/15 19:06:06時点 Amazon調べ-詳細)

最新機種でVlogの思い出を撮影しよう!

ペヤング ソースやきそば 120g×18個

created by Rinker
ペヤング
¥2,600 (2024/03/15 19:03:46時点 Amazon調べ-詳細)

とりあえず保存食として買っておけば間違いなし!

ドラゴンクエスト メタリックモンスターズギャラリー メタルキング

created by Rinker
スクウェア・エニックス(SQUARE ENIX)
¥3,250 (2024/03/15 19:03:48時点 Amazon調べ-詳細)

みんな大好き経験値の塊をデスクに常備しておこう!

Bauhutte ( バウヒュッテ ) 昇降式 L字デスク ブラック BHD-670H-BK

created by Rinker
Bauhutte(バウヒュッテ)
¥13,861 (2024/03/15 15:06:46時点 Amazon調べ-詳細)

メインデスクの横に置くのにぴったりなおしゃれな可動式ラック!

BANDAI SPIRITS ULTIMAGEAR 遊戯王 千年パズル 1/1スケール

created by Rinker
BANDAI SPIRITS(バンダイ スピリッツ)
¥7,180 (2024/03/15 15:06:46時点 Amazon調べ-詳細)

もう一人の僕を呼び覚ませ!!

MOFT X 【新型 ミニマム版】 iPhone対応 スマホスタンド

created by Rinker
MOFT
¥2,880 (2024/03/15 19:06:03時点 Amazon調べ-詳細)

Amazon一番人気のスマホスタンド!カード類も収納出来てかさ張らないのでオススメです!

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オブジェクトを生成することが可能になりました。

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

CATEGORIES & TAGS

IT