標籤:
被標記為transient的屬性在對象被序列化的時候不會被儲存
int[] arr1 = {1, 2, 3, 4, 5};
int[] arr2 = Arrays.copyOf(arr1, new_length);//Arrays是數組的工具類
//ArrayList的轉化為靜態數組的toArray方法就是這個原理
//ArrayList的擴容原理也是Arrays.copyOf()方法
//建立了一個數組
定義一個數組int[] a={3,1,4,2,5}; int[] b=a; 數組b只是對數組a的又一個引用,即淺拷貝。
如果改變數組b中元素的值,其實是改變了數組a的元素的值
要實現深度複製,可以用clone或者System.arrayCopy
如下面的代碼
1 int[] a={3,1,4,2,5};
2 int[] b=a.clone();
3 b[0]=10;
4 System.out.println(b[0]+" "+a[0]);
輸出為10 3
可見改變了b的值,但是沒有改變a的元素的值
除了不同步和允許使用 null 之外,HashMap 類與 Hashtable 大致相同。HashMap不是安全執行緒的,如果想要安全執行緒的HashMap,可以通過Collections類的靜態方法synchronizedMap獲得安全執行緒的HashMap。
Map map = Collections.synchronizedMap(new HashMap());
在java程式設計語言中,最基本的結構就是兩種,一個是數組,另外一個是類比指標(引用),所有的資料結構都可
以用這兩個基本結構來構造的,HashMap也不例外。HashMap實際上是一個“鏈表散列”的資料結構,即數組和鏈
表的結合體。它之所以有相當快的查詢速度主要是因為它是通過計算散列碼來決定儲存的位置。
HashMap中主要是通過key的hashCode來計算hash值的,只要hashCode相同,計算出來的hash值就一樣。如果儲存的對象對多了,就有可能不同的對象所算出來的hash值是相同的,這就出現了所謂的hash衝突。學過資料結構的同學都知道,解決hash衝突的方法有很多,HashMap底層是通過鏈表來解決hash衝突的。
當我們往HashMap中put元素的時候,先根據key的hashCode重新計算hash值,根據hash值得到這個元素在數組中
的位置(即下標),如果數組該位置上已經存放有其他元素了,那麼在這個位置上的元素將以鏈表的形式存放,
新加入的放在鏈頭,最先加入的放在鏈尾。如果數組該位置上沒有元素,就直接將該元素放到此數組中的該位置
上。
HashMap其實就是一個Entry數組,Entry對象中包含了鍵和值,其中next也是一個Entry對象,它就是用來處理hash衝突的,形成一個鏈表。
loadFactor載入因子是表示Hsah表中元素的填滿的程度,
必須在 "衝突的機會"與"空間利用率"之間尋找一種平衡與折衷. 這種平衡與折衷本質上是資料結構中有名的"時-空"矛盾的平衡與折衷.
如果機器記憶體足夠,並且想要提高查詢速度的話可以將載入因子設定小一點;相反如果機器記憶體緊張,並且對查詢速度沒有什麼要求的話可以將載入因子設定大一點。不過一般我們都不用去設定它,讓它取預設值0.75就好了。
// 若“key為null”,則將該索引值對添加到table[0]中。
HashMap中則通過h&(length-1)的方法來代替模數,同樣實現了均勻的散列,但效率要高很多,這也是HashMap對Hashtable的一個改進。
length為2的n次方,為偶數,length-1為奇數,最後一位為1,(h為hash值)
length取2的整數次冪,是為了使不同hash值發生碰撞的機率較小,這樣就能使元素在雜湊表中均勻地散列。
如果這兩個 Entry 的 key 通過 equals 比較返回 true,新添加 Entry 的 value 將覆蓋集合中原有 Entry 的 value,但key不會覆蓋。如果這兩個 Entry 的 key 通過 equals 比較返回 false,新添加的 Entry 將與集合中原有 Entry 形成 Entry 鏈,而且新添加的 Entry 位於 Entry 鏈的頭部
當HashMap中的元素越來越多的時候,hash衝突的幾率也就越來越高,因為數組的長度是固定的。所以為了提高查詢的效率,就要對HashMap的數組進行擴容,數組擴容這個操作也會出現在ArrayList中,這是一個常用的操作,而在HashMap數組擴容之後,最消耗效能的點就出現了:原數組中的資料必須重新計算其在新數組中的位置,並放進去,這就是resize。
擴容是需要進行數組複製的,複製數組是非常消耗效能的操作,所以如果我們已經預知HashMap中元素的個數,那麼預設元素的個數能夠有效提高HashMap的效能
LinkedList底層的資料結構是基於雙向迴圈鏈表的,且頭結點中不存放資料,如下:
LinkedList<String> list = new LinkedList<String>(); 2 list.add("First"); 3 list.add("Second"); 4 list.add("Thrid"); 5 System.out.println(list); 6 ListIterator<String> itr = list.listIterator(); 7 while (itr.hasNext()) { 8 System.out.println(itr.next()); 9 }
Java集合類學習記錄