導入:なぜSequencedMapが重要なのか
これまでJavaのMapインターフェース(HashMapなど)は、基本的に「順序を保証しない」ことが前提でした。順序が必要な場合はLinkedHashMapを使っていましたが、先頭や末尾へのアクセス、あるいは逆順での反復処理を行うには、一度リストに変換したり、イテレータを複雑に操作したりする必要がありました。
Java 21で導入されたSequencedMapは、これらの「順序付きマップ」に対する操作を標準化し、直感的で効率的なAPIを提供します。これにより、コードの可読性が上がり、バグの混入を防ぐことができます。
基礎知識:SequencedMapとは?
SequencedMapは、その名の通り「要素が一定の順序で並んでいるMap」を扱うためのインターフェースです。
これまでJavaには「順序があるコレクション」としてListがありましたが、Mapには統一された階層がありませんでした。SequencedMapが登場したことで、LinkedHashMapなどのクラスがこのインターフェースを実装し、先頭や末尾への要素追加・取得・削除が統一されたメソッドで扱えるようになりました。
実装:主なメソッドの役割
SequencedMapで追加された主要なメソッドは以下の通りです。
・putFirst(K, V) / putLast(K, V): 先頭や末尾に要素を挿入します。
・firstEntry() / lastEntry(): 先頭や末尾の要素(Map.Entry)を取得します。
・pollFirstEntry() / pollLastEntry(): 先頭や末尾の要素を取得しつつ、マップから削除します。
・reversed(): 順序を逆転させたビュー(View)を返します。
サンプルプログラム
以下のコードをコピーして、Java 21以上の環境で実行してみてください。
import java.util.LinkedHashMap;
import java.util.SequencedMap;
public class SequencedMapExample {
public static void main(String[] args) {
// LinkedHashMapはSequencedMapを実装しています
SequencedMap map = new LinkedHashMap<>();
// データの追加
map.put("B", "中番目");
map.putFirst("A", "先頭"); // 先頭に追加
map.putLast("C", "末尾"); // 末尾に追加
System.out.println("現在のマップ: " + map);
// 先頭と末尾の取得
System.out.println("最初: " + map.firstEntry());
System.out.println("最後: " + map.lastEntry());
// 逆順での処理
System.out.print("逆順: ");
map.reversed().forEach((k, v) -> System.out.print(k + "=" + v + " "));
System.out.println();
// 要素の取り出しと削除
map.pollFirstEntry();
System.out.println("先頭削除後: " + map);
}
}
応用・注意点:現場で役立つアドバイス
1. ビュー(View)の性質を理解する: reversed()メソッドが返すのは、新しいマップをコピーしたものではなく「元のマップの逆順ビュー」です。そのため、reversed()後のマップに対して変更を加えると、元のマップにも反映されます。意図しない副作用を避けるため、この特性は必ず意識してください。
2. 既存コードからの移行: LinkedHashMapを独自に拡張して操作していた古いコードがある場合、SequencedMapのメソッドに置き換えることで、処理が格段に短くなります。
3. nullの扱い: LinkedHashMapなどはnullキーやnull値を許可しますが、実装クラスによって挙動が異なる場合があります。基本的にはキーと値の非null性を意識した設計を心がけましょう。
SequencedMapは、Javaのコレクションフレームワークをより現代的で扱いやすく進化させた重要な機能です。ぜひ今日からの開発に取り入れてみてください。

コメント