TreeMap:ソートされたキーと値のペア
TreeMap で順序を維持し、firstKey、lastKey、floorKey、ceilingKey を使って移動します。
「TreeMap:ソートされたキーと値のペア」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。
TreeMap とは
TreeMap は、Red-Black tree を基盤とするソート済みマップの実装です。キーは自然順序(またはカスタムコンパレータの順序)で昇順に維持されます。基本操作はすべて O(log n) です。
import java.util.TreeMap;
TreeMap<String, Integer> scores = new TreeMap<>();
scores.put("Charlie", 85);
scores.put("Alice", 92);
scores.put("Bob", 78);
// Iteration is in key order: Alice, Bob, Charlie
for (var entry : scores.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}firstKey、lastKey、floorKey、ceilingKey
TreeMap の NavigableMap インターフェースには、指定した値を基準にキーを検索するナビゲーションメソッドが用意されています:
TreeMap<Integer, String> map = new TreeMap<>();
map.put(10, "ten"); map.put(20, "twenty"); map.put(30, "thirty"); map.put(40, "forty");
System.out.println(map.firstKey()); // 10
System.out.println(map.lastKey()); // 40
System.out.println(map.floorKey(25)); // 20 (largest key ≤ 25)
System.out.println(map.ceilingKey(25)); // 30 (smallest key ≥ 25)
System.out.println(map.lowerKey(20)); // 10 (strictly less)
System.out.println(map.higherKey(20)); // 30 (strictly greater)エントリのナビゲーション
floorEntry、ceilingEntry、firstEntry、lastEntry は、キーだけでなく完全な Map.Entry を返します:
TreeMap<Integer, String> prices = new TreeMap<>();
prices.put(100, "Budget"); prices.put(300, "Standard"); prices.put(700, "Premium");
var entry = prices.floorEntry(350);
System.out.println(entry.getKey() + ": " + entry.getValue()); // 300: Standard
var top = prices.lastEntry();
System.out.println(top.getValue()); // PremiumsubMap、headMap、tailMap
TreeMap から範囲ビューを取得します。これらのビューは元のマップに連動するため、一方への変更はもう一方にも反映されます。
TreeMap<Integer, String> map = new TreeMap<>();
for (int i = 1; i <= 10; i++) map.put(i, "v"+i);
// Keys from 3 (inclusive) to 7 (exclusive)
System.out.println(map.subMap(3, 7)); // {3=v3, 4=v4, 5=v5, 6=v6}
// Keys strictly less than 5
System.out.println(map.headMap(5)); // {1=v1, 2=v2, 3=v3, 4=v4}
// Keys >= 7
System.out.println(map.tailMap(7)); // {7=v7, 8=v8, 9=v9, 10=v10}包含・排他的な境界
細かな境界制御には、オーバーロードされたバリエーションを使用します:
TreeMap<Integer, String> map = new TreeMap<>();
for (int i = 1; i <= 10; i++) map.put(i*10, "v"+i);
// From 30 (inclusive) to 60 (inclusive)
System.out.println(map.subMap(30, true, 60, true));
// {30=v3, 40=v4, 50=v5, 60=v6}降順
descendingMap() または descendingKeySet() を使用すると、キーを逆順に反復処理できます:
TreeMap<String, Integer> tm = new TreeMap<>();
tm.put("A", 1); tm.put("C", 3); tm.put("B", 2);
for (String key : tm.descendingKeySet()) {
System.out.print(key + " "); // C B A
}pollFirstEntry と pollLastEntry
先頭または末尾のエントリをアトミックに削除して返します。優先度付きマップの構築に便利です:
TreeMap<Integer, String> events = new TreeMap<>();
events.put(8, "Breakfast");
events.put(12, "Lunch");
events.put(18, "Dinner");
var first = events.pollFirstEntry(); // removes 8=Breakfast
System.out.println(first.getValue() + " removed");
System.out.println(events.firstKey()); // 12ユースケース: リーダーボード
リーダーボードでは、プレイヤーをスコア順に並べる必要があります。TreeMap はキーによって自動的にソートされます:
TreeMap<Integer, String> leaderboard = new TreeMap<>(Comparator.reverseOrder());
leaderboard.put(1200, "Alice");
leaderboard.put(1500, "Bob");
leaderboard.put(900, "Carol");
int rank = 1;
for (var e : leaderboard.entrySet()) {
System.out.println(rank++ + ". " + e.getValue() + " (" + e.getKey() + ")");
}
// 1. Bob (1500)
// 2. Alice (1200)
// 3. Carol (900)ユースケース: イベントスケジューラ
タイムスタンプをイベントに対応付け、指定した時刻より後に予定されている次のイベントを見つけるには ceilingEntry を使用します:
import java.time.LocalTime;
TreeMap<LocalTime, String> schedule = new TreeMap<>();
schedule.put(LocalTime.of(9,0), "Standup");
schedule.put(LocalTime.of(14,0), "Review");
schedule.put(LocalTime.of(17,0), "Retro");
LocalTime now = LocalTime.of(11, 30);
var next = schedule.ceilingEntry(now);
System.out.println("Next: " + next.getValue()); // ReviewTreeMap と HashMap のパフォーマンス
主な違い:
- HashMap: get/put は平均 O(1)、順序は保証されません
- TreeMap: get/put は O(log n)、キー順にソートされます
- LinkedHashMap: 平均 O(1)、挿入順になります
ソートされたキーや範囲クエリが必要な場合は TreeMap を使用してください。単純なキー検索では HashMap のほうが高速です。
スレッドセーフティ
TreeMap はスレッドセーフではありません。並行アクセスには、O(log n) の操作をサポートし、ソート順も維持する ConcurrentSkipListMap を使用してください。これにより、読み取りと書き込みを並行して実行できます。
確認問題
キーが {10, 20, 30, 40} の TreeMap<Integer, String> があります。map.floorKey(25) は何を返しますか?
まとめ: TreeMap
要点:
- TreeMap は Red-Black tree によってキーをソートされた昇順に維持します
- すべての操作は O(log n) です
- ナビゲーション: firstKey、lastKey、floorKey、ceilingKey、lowerKey、higherKey
- 範囲ビュー: subMap、headMap、tailMap(元のマップに連動するビュー)
- スレッドセーフなソート済みマップには ConcurrentSkipListMap を使用します
よくある質問
「TreeMap:ソートされたキーと値のペア」レッスンは無料ですか?
はい。「TreeMap:ソートされたキーと値のペア」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。
「TreeMap:ソートされたキーと値のペア」で何を学びますか?
TreeMap で順序を維持し、firstKey、lastKey、floorKey、ceilingKey を使って移動します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Java Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「TreeMap:ソートされたキーと値のペア」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJava Academyレッスンでコードを書いて実行できますか?
はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- TreeMap:ソートされたキーと値のペア
- サブマップと範囲ビュー
- TreeSet と NavigableSet
- Tree コレクションのカスタム順序