Java集合クラスとその運用総括と経験の共有を深く理解する


忠所周知java集合類の運用は非常に広く、面接の時に面接官がよく聞くhashMapとhashTableの違いは、collection集合類のいくつかの形式(set,map,list)を例に挙げて説明し、それぞれの違いを説明する.一般arraylist実装クラスの使用,mapの使用など,普段から用いられている各種集合クラスの選択や異なる運用シーンでの使用が大きい.次にリスト、set、mapの紹介、collectionのiteratorの紹介から、集合類に対する印象をさらに大きくします.Listは、Vector、LinkedList、ArrayListなど、よく使われる実装クラスを含む秩序ある繰り返し可能な集合インタフェースであり、listの重要な特徴は、集合中の各要素に対応する順序があることであり、VectorとArrayListの主な違いは、Vectorがスレッドが安全であることであり、ArrayListはそうではなく、ここで多くの初心者が愚かになる可能性がある.スレッドセキュリティとはどのような概念なのか、スレッドセキュリティといえば、まず2つの名詞を説明しなければなりません.1つはワークメモリと呼ばれ、もう1つはメインメモリと呼ばれています.ワークメモリとはjava仮想マシンが使用しているlistオブジェクトに割り当てたメモリを指し、メインメモリはプログラムがメインスレッドを実行するために使用するメモリです.listを操作すると、Vectorスレッドセキュリティとはlistがワークメモリで動作することを意味し、java仮想マシンはこのスレッドにスレッドロックを割り当てます.すなわち、オブジェクトがスレッドロックを占有しているときに他のスレッドがこのオブジェクトを修正するために占有ロックを必要とするオブジェクトがロックを主に解放したり、ロックがタイムアウトしたりします.ここで我々が一般的に使用するlistの実装クラスは一般にArrayListであるが,Vectorを使用する場合には集合の効率が大幅に低下するため,複数のスレッドが同じlistを同時に操作するとConcurrentModificationExceptionが現れる.次に我々のLinkedListについて述べるが、LinkedListはlistのチェーンテーブル実装方式であり、要素の挿入・削除速度が非常に速い場合、ArrayListは要素の挿入・削除を行う時間の複雑度がO(n)であり、LinkedListはO(1)であり、それ自体にlistのポインタが存在するため、ArrayListはLinkedListよりも検索速度がずっと速い.
setセットの最大の特徴は、繰り返さない必要がないことです.setは、2つの要素が一致するか否かを判断する方法がequalsであり、equalsがfalseである場合、この2つの要素は同時に存在することを許さない.HashSetはsetインタフェースの重要な実装であり、HashSetはsetのhashcode()法によってsetに対応するハッシュコードを計算するため、多くの記憶と検索性能を有する.HashSetはnull要素を保存できます.HashSetは初期化時に16の初期容量と0.75のロードファクタを有し、hashsetの長さが16*0.75に達するとjava仮想機会はその長さをrehashし、16*2、すなわち32となり、その容量サイズは2の次べき乗でなければならない.この特性はHashSetの下層実装hashMapによって決定される.特筆すべきは、ロードファクタが小さい場合、クエリーの効率は大きくなるが、浪費される空間も大きく、ロードファクタが大きい場合、浪費される空間は小さく、クエリーの効率が悪い場合、データの衝突が発生しやすいことである.次にhashSetのソースコードの一部を見てみましょう.
public class HashSet extends AbstractSet implements Set, Cloneable,Serializable {
               private transient HashMap map;
               private static final Object PRESENT = new Object();

               public HashSet() {
                   map = new HashMap();
               }
               public Iterator iterator() {
                   return map.keySet().iterator();
               }
               public boolean add(E e) {
                   return map.put(e, PRESENT)==null;
               }
               public boolean remove(Object o) {
                   return map.remove(o)==PRESENT;
               }
           }

HashSetのソースコードから、その下位層がHashMap構成であることがわかります.HashSetにデータを格納するとき、格納されているのはHashMapのキー値で、それらのvalueはすべて同じです.private static filna Object PRESENT=new Object()です.HashSetのHashテーブルへの格納には、key、value、hashcodeの計3列が含まれています.HashSetのaddメソッドを呼び出すと、java仮想マシンはまずvalue値のhashcodeを計算し、hashcodeで計算したインデックスに基づいて遍歴し、keyのequalsメソッドを呼び出します.vlaueがすでに存在する場合は、元の指を置き換え、前の値を返します.そうでなければnullを返します.ここで,我々のHashSetもスレッドが同期していない.次にmapについてお話しします.mapはマッピング関係のあるデータを保存するために使用されます.mapインタフェースには、HashMap、HashTable、TreeMapのいくつかの一般的な実装クラスがあります.TreeMapは、TreeMap内のすべてのkeyを赤と黒のツリーに基づいてソートし、HashMapとHasTableの違いは2点あれば、1つはhashTableがスレッドが安全でHashMapがそうではなく、2つはhashMapがkeyとvalueとしてnullを許可することであり、ここで注意しなければならないのは、HashMapはnullとして1つのkeyしかなく、nullとして複数のvalueが許可されることである.前述したcollection集合クラスのいくつかの特徴について説明したが,以下の集合クラスのいくつかの関連を説明すると,SetとMapの関係,Mapのkeyのすべてのkey集合が結合してSet集合であるため,mapではSet keySet()メソッドを提供してすべてのkeyからなるset集合を返す.MapとListの関係は,Map集合のkey-valueがListの1つのオブジェクトに相当する.