JavaのMap

Java本格入門のmapの部分を読んだので、それのメモ
(深い内容は書いてません)

Map・・・キーと値の組み合わせで複数要素を扱うことができる。

Mapの基本的な使い方
public class Main {
    
    public static void main(String[] args) {
        Map<String, Integer> scores = new HashMap<>();

        //値の追加
        scores.put("takahashi", 100);
        scores.put("yamada", 78);
        scores.put("sasaki", 50);
        System.out.println("Mapの中身" + scores.toString());
        //→ Mapの中身{sasaki=50, takahashi=100, yamada=78}

        //値の上書き
        scores.put("yamada", 90);
        System.out.println("Mapの中身" + scores.toString());
        ///→ Mapの中身{sasaki=50, takahashi=100, yamada=90}

        //値の取得。
        //キーが存在しない場合はnullが入る。
        //ただしだからと言ってキーの存在をチェックできるわけではない。
        //意図的に値をnullとしている場合、キーが存在するのかしないのかの区別がつかない。
        Integer score = scores.get("yamada");
        System.out.println(score);
        //→ 90

        //値の削除
        scores.remove("yamada");
        System.out.println("Mapの中身" + scores.toString());
        ///→ mapの中身{sasaki=50, takahashi=100}

        //サイズを取得
        int size = scores.size();
        System.out.println(size);
        //→ 2

        //キーの検索
        boolean existKey = scores.containsKey("yamada");
        System.out.println(existKey);
        //→ false

        //値の検索
        boolean existValue = scores.containsValue(100);
        System.out.println(existValue);
        //→ true

    }
}
Mapの3つの実装クラス

・HashMap

この実装はsynchronizedされません。複数のスレッドが並行してハッシュ・マップにアクセスし、それらのスレッドの少なくとも1つが構造的にマップを変更する場合は、外部でその同期をとる必要があります。

スレッドセーフじゃないらしい。
なので、Collections.synchronizedMapメソッドを使用してマップを「ラップ」するのがいいとのこと。

  Map m = Collections.synchronizedMap(new HashMap(...));


・LinkedHashMap

HashMapのサブクラス。
HashMapが順序に対して保証しないのに対し、LinkedHashMapはputした順番に格納される。

public class Main {
    
    public static void main(String[] args) {
        //・HashMapの場合
        Map<Integer, String> hmap = new HashMap<>();
        MapTest test = new MapTest();

        test.test(hmap, 4, "d");
        test.test(hmap, 45, "bbb");
        test.test(hmap, 1, "a");
        
        System.out.println(hmap);
        //→ {1=a, 4=d, 45=bbb}
        //挿入した順番になっていない

        //・LinkedHashMapの場合
        Map<Integer, String> lmap = new LinkedHashMap<>();
        MapTest test2 = new MapTest();

        test2.test(lmap, 3, "T");
        test2.test(lmap, 34, "FG");
        test2.test(lmap, 7, "W");

        System.out.println(lmap);
        //→ {3=T, 34=FG, 7=W}
        //挿入した順番になっている

    }
}


・TreeMap

キーの値を元に、2分探索木のアルゴリズムで要素をソートするクラス。
データが自動的にソートされるらしい。

「〇〇以上〇〇以下のキーを持つ要素の取得」
「〇〇より大きな、もっとも近いキーを持つ要素を取得」
などのように、大小を意識した値の取得ができる。

Mapの実装クラスの使い分け

キーの大小を意識した部分集合を扱う場合 → TreeMap

要素の順序を保持する必要がある場合 → LinkedHashMamp

複数スレッドから同時にアクセスする場合 → ConcurrentHashMap

それ以外 → HashMap

雑多メモ

・ConcurrentModificationException

あるスレッドがCollectionで反復処理を行っている間に、別のスレッドがそのCollectionを変更することは一般に許可されません。通常、そのような環境では、反復処理の結果は保証されません。いくつかのイテレータ(Iterator)の実装(JREが提供するすべての一般的な目的のコレクションの実装の、イテレータの実装を含む)は、その動作が検出された場合にこの例外をスローすることを選択できます。この例外をスローするイテレータは、フェイルファスト・イテレータと呼ばれます。

まとめ

mapについて調べてみたが、内部構造(ハッシュ テーブルがどうのこうの)などはいまいち理解できてないので、
どこかのタイミングで深くみてみたいところ。。。。

おわり