一、集合的定義
集合:是在計算機中用於存儲一種或多種引用類型數據,並且長度可變的容器。
外延:List集合、Queue集合、Set集合
二、各類集合的特點
List集合(繼承Collection接口):有序存儲可重複元素
外延:ArrayList集合、Vector集合、LinkedList集合
ArrayList集合:基於數組實現、長度可變的、分配連續內存空間的List集合。特點:線程異步、線程不安全、效率高 遍歷以及隨機訪問元素的效率高
Vector集合:基於數組實現的,線程同步的遺留集合類。特點:線程同步的、多線程安全的、效率低
LinkedList集合:採用鏈表存儲方式,實現了List接口和Queue接口的集合。 插入,刪除元素效率比較高
LinkedList實現了 List、Deque、Queue 接口
List集合實現類的使用場合:
要求快速訪問元素,則使用ArrayList 集合。
要求快速插入和刪除元素,則使用LinkedList集合。
當對多線程元素操作時,則使用Vector集合。
要求數據先進後出時,則使用Stack集合類。
Queue集合(繼承Collection接口)(隊列 先進先出):用於存儲 可重複元素的、先進先出的集合。(只允許在表的前端進行刪除操作,而在表的後端進行插入操作的線性表 )
Queue接口實現類:LinkedList、PriorityQueue
常用數據結構:
Set集合(繼承Collection接口):用於無序存儲不可重複元素的集合(不可通過索引訪問元素)
實現類:HashSet集合、LinkedHashSet集合、TreeSet集合
HashSet集合:基於哈希表(jdk1.8版本之前:哈希表=數組+鏈表
jdk1.8版本之後: 哈希表 = 數組 + 鏈表 或 哈希表 = 數組 + 紅黑樹(提高查找速度)
)的Set集合。
鏈表長度達到8個,數組的長度達到64個,則鏈表將轉換爲紅黑樹。
紅黑樹轉鏈表位桶節點數量最小值 6。
HashSet集合存儲步驟:
1.使用哈希算法計算元素對應的哈希值,使用此哈希值作爲地址存儲(hashCode()方法)
2.判斷此哈希值對應的位置上是否已經存有元素
3.若沒有就將此元素存儲到該位置上
4.若有則使用equals方法判斷兩個對象是否相等,相等就不存儲,不相等則與上個元素存在一起
重寫hashCode() 用於獲得元素的存儲位置
重寫equals() 用於在兩個元素位置相同的時候比較兩個元素是否相等
實體類重寫以上兩個方法可以避免添加重複對象
LinkedHashSet集合:基於雙向鏈表和哈希表、繼承自HashSet的Set集合。
使用鏈表維護輸入順序
TreeSet集合:基於紅黑樹、實現了Set接口,具有排序功能的Set集合。
實體類進行treeset排序時需要實現Comparable接口
Comparable接口:使實現類自身具備某種比較規則以便對其對象進行 自然排序的接口。
自然排序:是要求自定義類實現Comparable接口並實現其compareTo(Object obj)方法,在此方法中指定排序規則的算法。
public class Student implements Comparable {
public int compareTo(Student o) {//重寫比較方法,返回值爲整數
return this.age - o.age;//結果爲負數,排在o對象之前
// 結果爲正數,排在o對象之後
// 結果爲0,說明兩個對象相等
//返回年齡的差,說明年齡小的排在前
}
}
//如果插入年齡相同的兩個對象,則按照姓名排序
public class Student implements Comparable {
public int compareTo(Student o) {
if(this.age == o.age)
return this.name.compareTo(o.name);
return this.age - o.age;
}
}
Comparator比較器: 在外部自定義比較規則以便容器對其存儲數據進行 定製排序的對象。
定製排序:是要求自定義類實現Compartor接口並重寫其compare(Object arg0, Object arg1)方法,在此方法中依據 XX 屬性進行排序的算法。也稱比較器排序。
使用自定義比較器時注意:將比較器作爲參數傳入TreeSet構造器中
//創建比較器類 MyComparator
public class MyComparator implements Comparator{
public int compare(Object arg0, Object arg1) {
Student o1=(Student)arg0;
Student o2=(Student)arg1;
if(o1.getAge() == o2.getAge())
return o1.getName().compareTo(o2.getName());
return o1.getAge() - o2.getAge();
}
}
TreeSet set = new TreeSet(new MyComparator());//將比較器作爲參數傳入TreeSet構造器中
set.add(new Student(“Joker", 18));
set.add(new Student(“Faker", 16));
set.add(new Student(“Sky", 23));
set.add(new Student(“Petter", 23));
for (Student s : set) {
System.out.println(s);
}
Set集合的使用場景:
當要求數據是不重複,且無序的可用HashSet集合。
當要求數據不能重複,且要排序並不能爲空選擇TreeSet集合
Map集合:容器框架中以鍵值對形式存儲元素的容器。
實現類:HashMap 、TreeMap、Hashtable
HashMap集合:基於哈希表實現、線程不安全的Map容器
實現類:LinkedHashMap
HashSet底層是HashMap實現的。
HashMap遍歷輸出的方法:
keySet() 獲取所有鍵的集合
values() 獲取所有值得集合
entry() 遍歷輸出鍵值對
注意:hashMap集合添加key=自定義對象元素時,該對象需重寫hashCode()和equals()方法
hashMap:key可以爲null,且key唯一、value可以爲null,且多個value可以重複、線程不安全
LinkedHashMap集合:是繼承自HashMap,基於雙向鏈表存取有序 的Map容器。(哈希表+雙向鏈表)
特點:LinkedkedHashSet底層就是LinkedHashMap實現的
LinkedHashMap是HashMap的子類; 只是比HashMap多了一條鏈,用於保存添加元素的順序。
key唯一,value不唯一 、key value 都可爲空 線程不安全、輸出順序與添加順序一致。
Hashtable集合:是基於基於哈希表實現的、線程安全的Map容器。
特點:key唯一,value不唯一 key value 都不可爲空 線程安全
TreeMap集合:是基於紅黑樹實現的、具有排序功能的Map容器。(根據其鍵進行自然排序的功能、根據創建對象時提供的 Comparator 進行排序)
特點 :TreeSet底層就是TreeMap實現的
key唯一,value不唯一 針對鍵排序 線程非安全 key不可以爲null
注意:遍歷時需定製比較規則 (1.創建比較器類實現Comparator 2.TreeMap<Person,String> t = new TreeMap<Person,String>(new MyComparator()) ;)
Map集合的使用場合:
當需要存儲鍵值對,都是無序的首選HashMap 。
當需要存儲鍵值對並按 key 排序可以選擇TreeMap。
當需要存儲鍵值對並保持插入順序選擇LinkedHashMap 。
需要線程同步,首選Hashtable。
三、迭代器(Iterator)
使用演示:
調用Iterator()得到一個指向集合序列第一個元素的迭代器;
用循環調用hasNext()方法,如果有元素,返回true;
在循環中,使用next()方法獲得集合的下一個元素;
ArrayList dogs = new ArrayList();
Iterator it=dogs.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
ListIterator迭代器(列表迭代器):
在iterator的基礎上新增的一種迭代器,它新增了hasprevious()和previous()方法,可以進行向前遍歷。具有雙向遍歷列表的功能。
ArrayList dogs = new ArrayList();
…
dogs.add(ououDog);
dogs.add(yayaDog);
dogs.add(meimeiDog);
dogs.add(feifeiDog);
ListIterator iter = dogs.listIterator() ;
System.out.println(“由前向後輸出:”) ;
while(iter.hasNext()){ 判斷是否有下一個元素
Dog dog = iter.next() ; 遍歷下一個元素
System.out.print("\t"+dog + “\n”) ;
}
System.out.println("\n由後向前輸出:") ;
while(iter.hasPrevious()){ 判斷是否有前一個元素
Dog dog = iter.previous() ; 遍歷前一個元素
System.out.print("\t"+dog + “\n”) ;
}
foreach的使用:
for(元素類型t 元素變量x : 遍歷對象obj){ 引用了x的java語句; }
for(Dog dog:dogs){
System.out.print("\t"+dog + “\n”) ;
//foreach一般只用於遍歷集合!
}
foreach的特點:
java5的新特徵 、for語句的特殊簡化版本 遍歷數組、集合方便
三種集合遍歷方式:
//for循環
for (int i = 0; i < 1000000; i++) {
temp = list.get(i);
syso(temp);
}
//迭代器
while(it.hasNext()){
temp = it.next();
syso(temp);
}
//foreach
for(Object t : list)
temp = t;
syso(temp);
}
效率:for循環>iterator迭代器>foreach