Java SE 核心 II【Collection 集合框架】

Collection集合框架html

 


  在實際開發中,須要將使用的對象存儲於特定數據結構的容器中。而 JDK 提供了這樣的容器——集合框架,集合框架中包含了一系列不一樣數據結構(線性表、查找表)的實現類。
集合的引入:
數組的優點:是一種簡單的線性序列,能夠快速地訪問數組元素,效率高。若是從效率和類型檢查的角度講,數組是最好的。
數組的劣勢:不靈活。容量須要事先定義好,不能隨着需求的變化而擴容。
1)Collection 經常使用方法:
①int size():返回包含對象個數。 ②boolean isEmpty():返回是否爲空。
③boolean contains(Object o):判斷是否包含指定對象。
④void clear():清空集合。 ⑤boolean add(E e):向集合中添加對象。
⑥boolean remove(Object o):從集合中刪除對象。
⑦boolean addAll(Collection<? extends E > c):另外一個集合中的全部元素添加到集合
⑧boolean removeAll(Collection<?> c):刪除集合中與另一個集合中相同的原素
⑨Iterator<E> iterator():返回該集合的對應的迭代器
2)Collection 和 Collentions 的區別
  Collection 是 java.util 下的接口,它是各類集合的父接口,繼承於它的接口主要有 Set和 List;
  Collections 是個 java.util 下的類,是針對集合的幫助類,提供一系列靜態方法實現對各類集合的搜索、排序、線程安全化等操做。
一、List集合的實現類(ArrayList、LinkedList和Vector
List 接口是 Collection 的子接口,用於定義線性表數據結構,元素可重複、有序的;能夠將 List 理解爲存放對象的數組,只不過元素個數能夠動態的增長或減小。
1)List 接口的兩個常見的實現類:ArrayList 和 LinkedList,分別用動態數組和鏈表的方式實現了 List 接口。List、ArrayList 和 LinkedList 均處於 java.util 包下。
2)能夠認爲 ArrayList 和 LinkedList 的方法在邏輯上徹底同樣,只是在性能上有必定的差異,ArrayList 更適合於隨機訪問,而 LinkedList 更適合於插入和刪除,在性能要求不是特別苛刻的情形下能夠忽略這個差異。
List接口經常使用的實現類有3個:ArrayList、LinkedList和Vector。
java


ArrayList查詢效率高,增刪效率低,線程不安全。咱們通常使用它算法

  1 package boom.collection;
  2 
  3 import java.util.ArrayList;
  4 import java.util.Collection;
  5 import java.util.Iterator;
  6 import java.util.List;
  7 import java.util.ListIterator;
  8 
  9 /**
 10  * 測試collection接口的方法 List接口
 11  * 
 12  * @author Administrator
 13  *
 14  */
 15 public class ListTest {
 16 
 17     public static void main(String[] args) {
 18          //test01();
 19         //test02();
 20         test03();
 21 
 22     }
 23 
 24     /**
 25      * 集合帶索引順序的相關方法
 26      */
 27     public static void test03() {
 28         List<String> list = new ArrayList<>();
 29         
 30         // 添加元素
 31         list.add("京東");
 32         list.add("阿里");
 33         list.add("騰訊");
 34         list.add("百度");
 35         System.out.println(list);// [京東, 阿里, 騰訊, 百度]
 36         
 37         // 在指定索引位置插入新元素:index[0]
 38         list.add(0, "網易");
 39         System.out.println(list);// [網易, 京東, 阿里, 騰訊, 百度]
 40         
 41         // 移除指定位置的元素:index[3]
 42         list.remove(3);
 43         System.out.println(list);// [網易, 京東, 阿里, 百度]
 44         
 45         // 指定位置更改元素:index[0]
 46         list.set(0,"Google");
 47         System.out.println(list);// [Google, 京東, 阿里, 百度]
 48         // 得到更改的元素
 49         System.out.println(list.get(0));// Google
 50         
 51         
 52         list.add("阿里");
 53         System.out.println(list);// [Google, 京東, 阿里, 百度, 阿里]
 54         // 順序查找(角標0開始)指定的元素下標
 55         System.out.println(list.indexOf("阿里"));// 2
 56         // 從後往前找
 57         System.out.println(list.lastIndexOf("阿里"));// 4
 58         
 59             
 60     }
 61 
 62     /**
 63      * ArrayList_操做多個List_並集和交集及兩個list之間操做元素
 64      */
 65     public static void test02() {
 66         List<String> list01 = new ArrayList<String>();
 67         list01.add("AAA");
 68         list01.add("BBB");
 69         list01.add("CCC");
 70         
 71         List<String> list02 = new ArrayList<String>();
 72         list02.add("DDD");
 73         list02.add("CCC");
 74         list02.add("EEE");
 75         
 76         // 打印list01集合元素內容
 77         System.out.println(list01); // [AAA, BBB, CCC]
 78         
 79         // 把list02集合裏全部的元素都添加到list01集合裏:在末尾進行添加
 80         list01.addAll(list02);
 81         System.out.println(list01); // [AAA, BBB, CCC, DDD, CCC, EEE]
 82         
 83         // 把list02集合裏的全部元素添加到01集合裏指定的位置,根據索引
 84         list01.addAll(2, list02);
 85         System.out.println(list01);// [AAA, BBB, DDD, CCC, EEE, CCC, DDD, CCC, EEE]
 86         
 87         // 01集合裏是否包含02集合的全部元素 :true or false
 88         System.out.println(list01.contains(list02)); // false
 89         
 90         
 91         // 先進行打印,方便看效果
 92         System.out.println("list01:"+list01); // list01:[AAA, BBB, DDD, CCC, EEE, CCC, DDD, CCC, EEE]
 93         System.out.println("list02:"+list02); // list02:[DDD, CCC, EEE]
 94         
 95         //移除集合01和集合02中都包含的元素,返回01集合
 96         //list01.removeAll(list02);
 97         //System.out.println(list01);// [AAA, BBB]
 98         
 99         // 取本集合01和集合02中都包含的元素,移除非交集元素,返回01集合
100         list01.retainAll(list02);
101         System.out.println(list01); // [DDD, CCC, EEE, CCC, DDD, CCC, EEE]
102         
103     }
104 
105     /**
106      * List接口經常使用方法
107      */
108     public static void test01() {
109         List<String> list = new ArrayList<String>();
110         // 判斷集合是否爲空
111         System.out.println(list.isEmpty());// true
112         
113         // 添加add,按下標順序添加
114         list.add("國產001");
115         list.add("國產002");
116         list.add("國產003");
117         
118         System.out.println(list.isEmpty());// false
119         
120         // 打印 list自動調用toString方法
121         System.out.println(list.toString()); // [國產001, 國產002, 國產003]
122         System.out.println("集合的長度:" + list.size());// 集合的長度:3
123 
124         // 指定位置索引添加元素
125         list.add(0, "new");// 在下標0的位置添加新元素 "new"
126         System.out.println(list); // [new, 國產001, 國產002, 國產003]
127 
128         // 移除
129         list.remove(0);// 移除下標爲0的元素
130         System.out.println(list);// [國產001, 國產002, 國產003]
131         
132         // 根據下標修改某個元素的值
133         // index[1]的位置更改成 "改"
134         list.set(1, "改");
135         System.out.println(list);// [國產001, 改, 國產003]
136 
137         // 測試集合是否包含指定的元素:true or false
138         System.out.println("是否包含指定元素:" + list.contains("國產"));// false
139         System.out.println("是否包含指定元素:" + list.contains("國產003"));// true
140 
141         // 清空集合全部的元素
142         list.clear();
143         System.out.println("清空全部元素:" + list); // 清空全部元素:[]
144 
145     }
146 }
ListTest Code

運行效果參照圖:

ArrayList_底層JDK源碼解讀
數組

ArrayList:底層是用可變長度數組實現的存儲。
特色:查詢效率高,增刪效率低,線程不安全。

一、數組長度是有限的,而ArrayList是能夠存聽任意數量的對象,長度不受限制。
二、那麼它是怎麼實現的呢?
  本質上就是經過定義新的更大的數組,將舊數組中的內容拷貝到新數組,來實現擴容。 ArrayList的Object數組初始化長度爲10,若是咱們存儲滿了這個數組,須要存儲第11個對象,就會定義新的長度更大的數組,並將原數組內容和新的元素一塊兒加入到新數組中。
LinkedList:底層用雙向鏈表實現的存儲。
特色:查詢效率低,增刪效率高,線程不安全。
安全


Vector:Vector底層是用數組實現的List,相關的方法都加了同步檢查,所以「線程安全,效率低」

二、泛型
1)泛型是 JDK1.5 引入的新特性,泛型的本質是參數化類型。在類、接口、方法的定義過程當中,所操做的數據類型爲傳入的指定參數類型。全部的集合類型都帶有泛型參數,這樣在建立集合時能夠指定放入集合中的對象類型。同時,編譯器會以此類型進行檢查。
2)ArrayList 支持泛型,泛型尖括號裏的符號可隨便些,但一般大寫 E。
3)迭代器也支持泛型,可是迭代器使用的泛型應該和它所迭代的集合的泛型類型一致!
4)泛型只支持引用類型,不支持基本類型,但可使用對應的包裝類
5)若是泛型不指定類型的話,默認爲 Object 類型。
三、List 高級-數據結構:Queue 隊列
  隊列(Queue)是經常使用的數據結構,能夠將隊列當作特殊的線性表,隊列限制了對線性表的訪問方式:只能從線性表的一端添加(offer)元素,從另外一端取出(poll)元素。Queue接口:在包 java.util.Queue。
1)隊列遵循先進先出原則:FIFO(First Input First Output)隊列不支持插隊,插隊是不道德的。
2)JDK 中提供了 Queue 接口,同時使得 LinkedList 實現了該接口(選擇 LinkedList 實現Queue 的緣由在於 Queue常常要進行插入和刪除的操做,而 LinkedList 在這方面效率較高)。
四、List 高級-數據結構:Deque 棧
  棧(Deque)是經常使用的數據結構,是 Queue 隊列的子接口,所以 LinkedList 也實現了 Deque接口。棧將雙端隊列限制爲只能從一端入隊和出隊,對棧而言便是入棧和出棧。例如:子彈夾就是一種棧結構。在包 java.util.Deque 下。
1)棧遵循先進後出的原則:FILO(First Input Last Output)。
2)經常使用方法:
①push:壓入,向棧中存入數據。
②pop:彈出,從棧中取出數據。
③peek:獲取棧頂位置的元素,但不取出
五、Set集合的實現類(HashSet 和 TreeSet )
Set容器特色:無序、不可重複。無序指Set中的元素沒有索引,咱們只能遍歷查找;不可重複指不容許加入重複的元素。更確切地講,新元素若是和Set中某個元素經過equals()方法對比爲true,則不能加入;甚至,Set中也只能放入一個null元素,不能多個。
1)HashSet 和 TreeSet 是 Set 集合的兩個常見的實現類,分別用 hash 表和排序二叉樹的方式實現了 Set 集合。HashSet 是使用散列算法實現 Set 的。
2)Set 集合沒有 get(int index)方法,咱們不能像使用 List 那樣,根據下標獲取元素。想獲取元素須要使用 Iterator。
3)向集合添加元素也使用 add 方法,可是 add 方法不是向集合末尾追加元素,由於無序。
HashSet:採用哈希算法實現,底層實際是用HashMap實現的(HashSet本質就是一個簡化版的HashMap),所以,查詢效率和增刪效率都比較高。
TreeSet:底層實際是用TreeMap實現的,內部維持了一個簡化版的TreeMap,經過key來存儲Set的元素。
(1) 因爲是二叉樹,須要對元素作內部排序。 若是要放入TreeSet中的類沒有實現Comparable接口,則會拋出異常:java.lang.ClassCastException。
(2) TreeSet中不能放入null元素。
六、Map集合的實現類(HashMap、TreeMap、HashTable、Properties等)
  Map就是用來存儲「鍵(key)-值(value) 對」的。 Map類中存儲的「鍵值對」經過鍵來標識,因此Key 不能重複,但所保存的 Value 能夠重複。
HashMap和HashTable
HashMap採用哈希算法實現,是Map接口最經常使用的實現類。 因爲底層採用了哈希表存儲數據,鍵不能重複,若是發生重複(是否重複經過equals方法),新的鍵值對會替換舊的鍵值對。
特色:HashMap在查找、刪除、修改方面都有很是高的效率。
HashTable類和HashMap用法幾乎同樣,底層實現幾乎同樣,只不過HashTable的方法添加了synchronized關鍵字確保線程同步檢查,效率較低。
HashMap與HashTable的區別
1. HashMap:線程不安全,效率高。容許key或value爲null。
2. HashTable:線程安全,效率低。不容許key或value爲null。
TreeMap使用和底層原理_Comparable接口_HashTable特色(HashTable: 線程安全,效率低。不容許key或value爲null。)
TreeMap是紅黑二叉樹的典型實現。咱們打開TreeMap的源碼,發現裏面有一行核心代碼:private transient Entry<K,V> root = null;
TreeMap和HashMap實現了一樣的接口Map,用法對於調用者來講沒有區別。HashMap效率高於TreeMap;在須要排序(comparable)的Map時才選用TreeMap。
數據結構

Collection集合框架的總結:
1. Collection 表示一組對象,它是集中、收集的意思,就是把一些數據收集起來。
2. Collection接口的兩個子接口:
  1) List中的元素有順序,可重複。經常使用的實現類有ArrayList、LinkedList和 vector。
    Ø ArrayList特色:查詢效率高,增刪效率低,線程不安全。
    Ø LinkedList特色:查詢效率低,增刪效率高,線程不安全。
    Ø vector特色:線程安全,效率低,其它特徵相似於ArrayList。
  2) Set中的元素沒有順序,不可重複。經常使用的實現類有HashSet和TreeSet。
    Ø HashSet特色:採用哈希算法實現,查詢效率和增刪效率都比較高。
    Ø TreeSet特色:內部須要對存儲的元素進行排序。所以,咱們對應的類須要實現Comparable接口。才能根據compareTo()方法比較對象之間的大小,才能進行內部排序。
3. 實現Map接口的類用來存儲鍵(key)-值(value) 對。Map 接口的實現類有HashMap和TreeMap等。Map類中存儲的鍵-值對經過鍵來標識,因此鍵值不能重複。
4. Iterator對象稱做迭代器,用以方便的實現對容器內元素的遍歷操做。
5. 類 java.util.Collections 提供了對Set、List、Map操做的工具方法。
6. 以下狀況,可能須要咱們重寫equals/hashCode方法:
  1) 要將咱們自定義的對象放入HashSet中處理。
  2) 要將咱們自定義的對象做爲HashMap的key處理。
  3) 放入Collection容器中的自定義對象後,可能會調用remove、contains等方法時。
7. JDK1.5之後增長了泛型。泛型的好處:
   1) 向集合添加數據時保證數據安全。
   2) 遍歷集合元素時不須要強制轉換。
框架

迭代器遍歷Iterator【List、Set、Map】ide

相關文章
相關標籤/搜索