導入
Java 21で導入されたSequenced Collectionsは、長年Java開発者を悩ませてきた「コレクションの先頭や末尾へのアクセス」や「逆順操作」を一気に解決する画期的なAPIです。これまで、リストを逆順に処理するために一時的なリストを作成したり、Collections.reverse()で破壊的な操作を行ったりしていた経験はありませんか? SequencedCollection.reversed()を使えば、元のコレクションを変更することなく、安全かつ簡潔に逆順ビューを取得できます。
基礎知識
SequencedCollectionは、Java 21から導入された新しいインターフェース階層です。ListやDequeなどの「順序を持つコレクション」がこのインターフェースを実装するようになりました。
重要ポイントは「ビュー(View)」であるという点です。 reversed()メソッドを呼び出すと、新しいリストがコピーされるわけではなく、元のコレクションへの「逆順の窓口」が返されます。そのため、メモリ効率が非常に高く、元のコレクションに対する変更が即座に反映されるという性質を持っています。
実装/解決策
SequencedCollectionのインターフェースが提供するreversed()メソッドを呼び出すだけで、逆順を走査するオブジェクトが得られます。このオブジェクトはそのまま拡張for文やStream APIで使用可能です。
現場でよくある「リストの末尾から処理したい」「逆順で検索したい」といったケースでは、コピーを作成するコストを払う必要がなくなります。
サンプルプログラム
以下のコードは、SequencedCollectionを利用して、元のリストを破壊せずに逆順で要素を出力する例です。
import java.util.ArrayList;
import java.util.List;
public class ReversedCollectionExample {
public static void main(String[] args) {
// SequencedCollectionを実装しているArrayListの作成
List<String> items = new ArrayList<>();
items.add("Java 8");
items.add("Java 11");
items.add("Java 21");
// reversed()で逆順ビューを取得(コピーは作成されない)
var reversedItems = items.reversed();
// 拡張for文でそのまま利用可能
System.out.println("逆順での出力:");
for (String item : reversedItems) {
System.out.println(item);
}
// ビューなので、元のリストを変更すると反映される
items.add("Java 25");
System.out.println("変更後の逆順ビューの先頭: " + reversedItems.getFirst());
}
}
応用・注意点
1. 副作用の理解: reversed()が返すのは「ビュー」です。つまり、reversedItemsに対してaddやremoveを行うと、元のitemsにもその変更が反映されます。意図しない副作用を避けるため、不変性が必要な場合は、List.copyOf(items.reversed())のようにして新しいリストへ変換してください。
2. Mapへの対応: MapもSequencedMapとして強化されており、同様にdescendingMap()(実質的なreversed)が利用可能です。KeyやValueの順序が重要なビジネスロジックでは、これらを活用することでコードの可読性が大幅に向上します。
3. 既存コードとの共存: Java 21以降の環境であれば、List型の変数をそのままSequencedCollectionとして扱うことができます。ただし、Java 17以前の環境ではコンパイルエラーになるため、ライブラリのバージョンアップ計画と併せて導入を検討してください。
このAPIは単なる便利機能ではなく、Javaのコレクションフレームワークの設計思想が「より直感的で安全な方向へ進化した」ことを示す重要なアップデートです。ぜひ積極的に活用してください。

コメント