# finally -> 03 【List、Set】
## 1.常用實現類
### 1.1 java.util.List
java.util.List是Collection接口的子接口,特點:
1. 可以存儲重復元素
2. 有先后順序
3. 有索引值
##### 常用的實現類有:
1. ArrayList:底層使用的是數組。查找快,增刪慢。
2. LinkedList:底層使用的是鏈表。增刪快,查找慢。
3. Vector:底層使用的也是數組,和ArrayList基本一樣,不過線程安全。
##### Collection接口的方法,我都有。但是我還有自己`特有`的方法:
public void add(int index, E element):添加一個元素到指定的索引位置。
public E remove(int index):根據指定的索引值刪除一個元素,返回被刪除的元素。
public E set(int index, E replacement):根據指定的索引值,替換一個元素,返回被替換掉的元素。
public E get(int index):根據指定的索引值獲取一個元素。
增刪改查:CRUD Create Read Update Delete
### 1.2 LinkedList
ArrayList底層使用數組,空間連續,查找快,增刪慢。
LinkedList底層使用鏈表,空間不連續,增刪快,查找慢。
Vector底層也是數組,和ArrayList基本一樣,但是線程安全,性能低。
##### LinkedList當中特有的方法:
public void addFirst(E e):在開頭添加一個元素
public void addLast(E e):在末尾添加一個元素
public E getFirst():獲取開頭的元素
public E getLast():獲取末尾的元素
public E removeFirst():刪除開頭的元素
public E removeLast():刪除末尾的元素
##### LinkedList當中有兩個與棧相關的方法:
public void push(E e):壓棧、進棧,在左邊添加一個元素。相當于addFirst方法。
public E pop():彈棧、出棧,在左邊刪除并取出一個元素。相當于removeFirst方法。
對于這兩個方法來說,數據元素的出入口全都是左邊。
### 1.3 java.util.set
java.util.Set是Collection的子接口。特點:
1. 不允許重復元素
2. 不保證先后順序
3. 沒有索引值
##### 常用子類:
1. HashSet:速度特別快,不保證順序。
2. LinkedHashSet:速度也很快,但是還能額外保證順序。
3. TreeSet:有大小排序功能。
`注意`:先后順序和大小排序是不一樣的!
##### HashSet集合是最常使用的Set集合,特點:
因為底層使用了一種名叫“哈希表”的數據結構,所以查找元素的速度嗷嗷快。
底層原理其實是在復用HashMap(明天學習)。
#### 【重點問題】
HashSet是如何判斷元素是否重復的?如何得知集合當中是否已經存在了重復的元素?
兩個對象是否相同,由equals和hashCode兩個方法共同決定。
## 2.hashCode
### 2.1來自java.lang.Object當中的方法:
public int hashCode():根據當前對象,產生一個“哈希值”(對象的特征碼)
如果沒有覆蓋重寫hashCode方法,那么Object當中的hashCode將會在JVM當中:
默認使用對象的內存地址值參與運算,然后得到一個與地址相關的int數字:哈希值。
只要內存夠用,可以創建很多個對象,無數個不同的地址值。
默認的哈希值只是使用了地址值參與運算而已,并不直接等于地址值。
無數種地址 --> 哈希運算hashCode() --> 42億種int哈希值
意味著:可能有不一樣的對象,哈希值是相同的。
如果自己編寫hashCode和equals方法,必須同時滿足3+5條原則。
##### hashCode方法的三條原則:
1. 運行期一致性。
2. 對象相同,那么哈希值必須相同。
3. 對象不同,那么哈希值不一定相同。
##### equals方法的五條原則:
1. `自反性`:自己和自己比較,一定相同。
2. `對稱性`:A比較B,B比較A,效果一樣。
3. `傳遞性`:如果AB一樣,并且BC一樣,那么AC也一樣。
4. `一致性`:只要對象的內容不變,比較的結果就不能變。
5. `非空性`:任何對象和null值比較,一定是false。
- 如果在哈希結構當中存儲自定義的類型,那么必須覆蓋重寫equals和hashCode方法。
- LinkedHashSet是HashSet的子類。
底層其實也有哈希表,速度也比較快,但是額外還添加了一層雙向鏈表,用來專門維護順序。
### 2.2 可變參數
可變參數就是參數的類型統一,但是個數隨意。是Java 5添加的特性之一。
##### 格式:
修飾符 返回值類型 方法名稱(參數類型... 參數名稱) {
方法體
}
##### `注意事項`:
1. 可變參數只是一個語法糖,底層其實就是普通的數組。
2. 方法的可變參數只能有一個
3. 方法的可變參數只能是最后一個
## 3.collections工具類
### 3.1常用的靜態方法
Collections是與集合相關的工具類,其中有常用的靜態方法:
public static void `shuffle`(List<?> list):打亂集合當中的順序。
public static boolean `addAll`(Collection c, T... elements):
第一個參數代表加到哪個集合中,第二個可變參數代表需要添加的元素都是誰。
public static void `sort`(List list):按照自然順序進行大小排序
public static void sort(List list, Comparator comp):第二個參數代表排序的規則。
### 3.2 兩個排序區別
public static void sort(List list, Comparator comp):第二個參數代表排序的規則。
##### 口訣:
1. 對于Comparable來說:升序就是我減他
2. 對于Comparator來說,升序就是一減二