集合
什麼是集合
概念
物件的容器,實現了對物件常用的操作
和陣列的區別
- 陣列長度固定,集合長度不固定
- 陣列可以儲存基本型別和引用型別,集合只能儲存引用型別
位置
java.util.*;
Collection體系
Collection 父介面
特點:代表一組任意型別的物件,無序、無下標、不能重複。
建立集合 Collection collection = new ArrayList();
常用方法
-
新增元素
collection.add();
-
刪除元素
collection.remove();
collection.clear();
-
遍歷元素(重點)
-
使用增強for(因為無下標)
for(Object object : collection){ }
-
使用迭代器
//haNext(); 有沒有下一個元素 //next(); 獲取下一個元素 //remove(); 刪除當前元素 Iterator it = collection.iterator(); while(it.hasNext()){ String object = (String)it.next(); //強轉 // 可以使用it.remove(); 進行移除元素 // collection.remove(); 不能用collection其他方法 會報併發修改異常 }
-
-
判斷
collection.contains();
collection.isEmpty();
List 子介面
特點:有序、有下標、元素可重複
建立集合物件 List list = new ArrayList<>( );
常用方法
-
新增元素
list.add( );
會對基本型別進行自動裝箱 -
刪除元素 可以用索引
list.remove(0)
當刪除數字與索引矛盾時 對數字強轉
list.remove((Object) 10)
或list.remove(new Integer(10))
-
遍歷
-
使用for遍歷
for(int i = 0; i < lise.size(); i++){ sout(list.get(i)); }
-
使用增強for
for(Object list: collection){ }
-
使用迭代器
Iterator it = collection.iterator(); while(it.hasNext()){ String object = (String)it.next(); //強轉 // 可以使用it.remove(); 進行移除元素 // collection.remove(); 不能用collection其他方法 會報併發修改異常 }
-
使用列表迭代器 ?(注意和迭代器區別)
ListIterator li = list.listIterator(); while(li.hasNext()){ System.out.println(li.nextIndex() + ":" + li.next()); //從前往後遍歷 } while(li.hasPrevious()){ System.out.println(li.previousIndex() + ":" + li.previous()); //從後往前遍歷 }
-
-
獲取
list.indexOf( );
-
返回子集合
sublist(x, y);
左閉右開List subList = list.subList(1, 3);
返回索引 1、2
List實現類
- ArrayList 【重點】
- 陣列結構實現,必須要連續空間,查詢快、增刪慢
- jdk1.2版本,執行效率塊、執行緒不安全
- Vector
- 陣列結構實現,查詢快、增刪慢
- jdk1.0版本,執行
- LinkedList
- 雙向連結串列結構實現,無需連續空間,增刪快,查詢慢
ArrayList
建立集合 ArrayList arrayList = new ArrayList<>();
-
新增元素
arrayList.add();
-
刪除元素
arrayList.remove(new Student("name", 10));
這裡重寫了 equals(this == obj) 方法
public boolean equals(Object obj){ //1 判斷是不是同一個物件 if(this == obj){ return true; } //2 判斷是否為空 if(obj == null){ return false; } //3 判斷是否是Student型別 if(obj instanceof Student){ Student == (Student)obj; //4 比較屬性 if(this.name.equals(s.getName()) && this.age == s.getAge()){ return true; } } //5 不滿足條件返回false return false; }
-
遍歷元素【重點】
-
使用迭代器
Iterator it = arrayList.iterator(); while(it.hasNext()){ Student s = (Student)it.next(); //強轉 }
-
列表迭代器
ListIterator li = arrayList.listIterator(); while(li.hasNext()){ Student s = (Student)li.next(); //從前往後遍歷 } while(li.hasPrevious()){ Student s = (Student)li.previous();//從後往前遍歷 }
-
-
判斷
arrayList.contains();
和arrayList.isEmpty();
-
查詢
arrayList.indexof();
原碼分析
DEFAULT_CAPACITY = 10; //預設容量
//注意:如果沒有向集合中新增任何元素時,容量0,新增一個後,容量為10
//每次擴容是原來的1.5倍
elementData存放元素的陣列
size 實際元素個數
Vector
建立集合 Vector vector = new Vector<>();
增加、刪除、判斷同上
遍歷中列舉器遍歷
Enumeration en = vector.elements();
while(en.hasMoreElements()){
String o = (String)en.nextElement();
sout(o);
}
LinkedList
建立連結串列集合 LinkedList li = new LinkedList<>();
常用方法與List一致
泛型
- 本質是引數化型別,把型別作為引數傳遞
- 常見形式有泛型類、泛型介面、泛型方法
- 語法
T成為型別佔位符,表示一種引用型別,可以寫多個逗號隔開 - 好處 1. 提高程式碼重用性 2. 防止型別轉換異常,提高程式碼安全性
泛型類
// 寫一個泛型類
public class MyGeneric<T>{
//使用泛型T
//1 建立變數
T t;
//2 泛型作為方法的引數
public void show(T t){
sout(t);
}
//3 泛型作為方法的返回值
public T getT(){
return t;
}
}
// 使用泛型類
public class TestGeneric{
public static void main(String[] args){
//使用泛型類建立物件
// 注意: 1. 泛型只能使用引用型別
// 2. 不用泛型型別物件之間不能相互賦值
MyGeneric<String> myGeneric = new MyGeneric<String>();
myGeneric.t = "hello";
myGeneric.show("hello world!");
String string = myGeneric.getT();
MyGeneric<Integer> myGeneric2 = new MyGeneric<Integer>();
myGeneric2.t = 100;
myGeneric2.show(200);
Integer integer = myGeneric2.getT();
}
}
泛型介面
語法:介面名
注意:不能泛型靜態常量
泛型方法
語法:
public class MyGenericMethod{
//泛型方法
public <T> T show(T t){
sout("泛型方法" + t);
return t;
}
}
//呼叫
MyGenericMethod myGenericMethod = new MyGenericMethod();
myGenericMethod.show("字串");// 自動型別為字串
myGenericMethod.show(200);// integer型別
myGenericMethod.show(3.14);// double型別
泛型集合
概念:引數化型別、型別安全的集合,強制集合元素的型別必須一致
特點:
- 編譯時即可檢查,而非執行時丟擲異常
- 訪問時,不必型別轉換(拆箱)
- 不同泛型之間應用不能相互賦值,泛型不存在多型
Set集合
特點:無序、無下標、元素不可重複
方法:全部繼承自Collection中的方法
增、刪、遍歷、判斷與collection一致
HashSet 【重點】
儲存結構:雜湊表(陣列+連結串列+紅黑樹)
儲存過程(重複依據)
- 根據hashCode計算儲存的位置,如果位置為空,直接儲存,若不為空,進行第二步
- 再執行equals方法,如果equals為true,則認為是重複,否則形成連結串列
特點
- 基於HashCode計算元素存放位置
- 利用31這個質數,減少雜湊衝突
- 31提高執行效率
31 * i = (i << 5) - i
轉為移位操作
- 31提高執行效率
- 當存入元素的雜湊碼相同時,會呼叫equals進行確認,如果結果為true,則拒絕後者存入
- 利用31這個質數,減少雜湊衝突
新建集合 HashSet<String> hashSet = new HashSet<String>();
新增元素 hashSet.add( );
刪除元素 hashSet.remove( );
遍歷操作
1. 增強for for( type type : hashSet)
2. 迭代器 Iterator<String> it = hashSet.iterator( );
判斷 hashSet.contains( );
hashSet.isEmpty();
TreeSet
特點
- 基於排列順序實現元素不重複
- 實現SortedSet介面,對集合元素自動排序
- 元素物件的型別必須實現Comparable介面,指定排序規則
- 通過CompareTo方法確定是否為重複元素
儲存結構:紅黑樹
建立集合 TreeSet<String> treeSet = new TreeSet<>()
新增元素 treeSet.add();
刪除元素 treeSet.remove();
遍歷 1. 增強for 2. 迭代器
判斷 treeSet.contains();
補充:TreeSet集合的使用
Comparator 實現定製比較(比較器)
Comparable 可比較的
// 重寫compare
@override
public int compare(Person o1, Person o2){
int n1 = o1.getAge()-o2.getAge();
int n2 = o1.getName().comareTo(o2.getName());
return n1 == 0 ? n2 : n1;
}
Map
Map介面的特點
1. 用於儲存任意鍵值對(key - value)
2. 鍵:無序、無下標、不允許重複(唯一)
3. 值:無序、無下標、允許重複
方法:
1. V put(K key, V value) 將物件存到集合中,關聯鍵值
2. Object get(Object key) 根據鍵獲得對應的值
3. Set<K> 返回所有的Key
4. Collection<V> values() 返回包含所有值的Collection集合
5. Set<Map.Entry<K, V>> 鍵值匹配的Set集合
Map介面的使用
//建立Map集合
Map<String, String> map = new HashMap<>();
// 1. 新增元素
map.put("cn", "中國");
map.put("uk", "英國");
map.put("cn", "zhongguo"); // 會替換第一個
// 2. 刪除
map.remove("uk");
// 3. 遍歷
// 3.1 使用KeySet()
//Set<String> keyset = map.keySet(); // 所有Key的set集合
for(String key : map.keyset){
sout(key + "---" + map.get(key));
}
// 3.2 使用entrySet()
//Set<Map.Entry<String, String>> entries = map.entrySet();
for(Map.Entry<String, String> entry : map.entries){
sout(entry.getKey() + "---" + entry.getValue();
}
HashMap 【重點】
儲存結構:雜湊表(陣列+連結串列+紅黑樹)
使用key可使hashcode和equals作為重複
增、刪、遍歷、判斷與上述一致
原碼分析總結:
- HashMap剛建立時,table是null,節省空間,當新增第一個元素時,table容量調整為16
- 當元素個數大於閾值(16*0.75 = 12)時,會進行擴容,擴容後的大小為原來的兩倍,目的是減少調整元素的個數
- jdk1.8 當每個連結串列長度 >8 ,並且陣列元素個數 ≥64時,會調整成紅黑樹,目的是提高效率
- jdk1.8 當連結串列長度 <6 時 調整成連結串列
- jdk1.8 以前,連結串列時頭插入,之後為尾插入
Hashtable
執行緒安全,執行效率慢;不允許null作為key或是value
Properties
hashtable的子類,要求key和value都是string,通常用於配置檔案的讀取
TreeMap
實現了SortedMap介面(是map的子介面),可以對key自動排序
Collection工具類
概念:集合工具類,定義了除了存取以外的集合常用方法
直接二分查詢int i = Collections.binarySearch(list, x);
成功返回索引
其他方法 : copy複製、reverse反轉、shuffle打亂
補充:
// list轉成陣列
Integer[] arr = list.toArray(new Integer[10]);
sout(arr.length);
sout(Array.toString(arr));
// 陣列轉成集合
// 此時為受限集合,不能 新增和刪除!
String[] name = {"張三","李四","王五"};
List<String> list2 = Arrays.asList(names);
// 把基本型別陣列轉為集合時,需要修改為包裝類
Integer[] nums = {100, 200, 300, 400, 500};
List<Integer> list3 = Arrays.asList(nums);