動態引用存儲——集合&&精確的集合定義——泛型
- 2019 年 10 月 6 日
- 筆記
前言:
對於面向對象的語言來說,為了方便對多個對象進行操作,就必須要對對象進行存儲。
使用數組來存儲對象的最大問題就是數組長度的固定性。(不靈活,難擴展)
Java集合又稱容器,可以動態的將對象的引用存儲在容器中。(靈活可擴展)
集合和數組區別
數組:
- 可以存儲同一類型的基本數據類型或者引用數據類型
- 長度固定
集合:
- 可以存儲不同類型的元素,但必須是引用數據類型
- 長度可變
集合概覽
Java集合類主要由Collection和Map派生而出。Collection是一個接口,是高度抽象出來的集合,它包含了集合的基本操作和屬性;Map是一個映射接口,即key-value鍵值對。

Collection
- List 有序可重複
- ArrayList
- LinkedList
- Vector
- Stack
- Set 無序不可重複
- HashSet
- LinkedSet
- TreeSet
ArrayList – LinkedList – Vector- Stack特點
- ArrayList : 異步,線程不安全,執行效率高;底層使用數組,存讀效率高,插入刪除效率低
- LinkedList:異步,使用雙向鏈表,插入刪除效率高
- Vector: 同步,線程安全,執行效率較低
- Stack:繼承Vector
從數據增長的角度看:
ArrayList和Vector都是使用數組(Array)來控制集合中的對象。
當你向兩種類型中增加元素的時候,如果元素的數目超過了內部數組目前的長度他們都需要擴展內部數組的長度。
Vector缺省情況下自動增長原來一倍的數組長度,ArrayList是原來的50%。
所以如果你要在集合中保存大量的數據,那麼使用Vector有一些優勢。
HashSet- LinkedSet-TreeSet特點
HashSet由HashMap實現,存取,查找性能強。
LinkedHashSet繼承HashSet。
TreeSet提供一個使用樹結構存儲Set接口的實現,對象以升序順序存儲,訪問和遍歷的時間很快。底層是TreeMap。
Map
- HashMap
- TreeMap
HashMap – TreeMap特點
HashMap通常比TreeMap快一點(樹和哈希表的數據結構使然),建議多使用HashMap,在需要排序的Map時候才用TreeMap。
HashMap的結果是沒有排序的,而TreeMap輸出的結果是排好序的。
Collection接口和Iterator接口常用方法


簡單使用:
1.HashSet
import java.util.Date; import java.util.HashSet; import java.util.Iterator; public class Main { public static void main(String[] args) { Date currentDate = new Date(); HashSet hs= new HashSet(); //添加元素 hs.add(currentDate.toString()); hs.add(new String("2")); hs.add("3"); hs.add("3");//不能包含重複元素,被自動覆蓋 System.out.println("for 迭代輸出"); for(Object element:hs) {System.out.println(element); } System.out.println("Iterator 迭代輸出"); Iterator iterator=hs.iterator(); while(iterator.hasNext()) { System.out.println(iterator.next()); } //刪除元素 hs.remove("2"); hs.remove(currentDate.toString()); System.out.println("刪除元素後輸出:"); for(Object element:hs) { System.out.println(element); } } }
2.TreeSet
//TreeSet默認自動排序 import java.util.TreeSet; import java.util.Iterator; public class Main { public static void main(String args[]) { TreeSet tr = new TreeSet(); tr.add("B"); tr.add("A"); tr.add("D"); tr.add("E"); System.out.println("直接輸出集合對象"); System.out.println(tr); System.out.println("for遍歷輸出"); for (Object element : tr) { System.out.println(element); } System.out.println("Iterator迭代輸出"); Iterator iterator = tr.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } }
3.LinkedList
import java.util.LinkedList; import java.util.Iterator; public class Main { public static void main(String []args) { LinkedList li= new LinkedList(); li.addFirst("C"); li.addLast("D"); li.addFirst("B"); li.addLast("E"); li.addFirst("A"); li.addLast("F"); System.out.println( "直接輸出"); System.out.println(li); System.out.println("--------------------"); System.out.println( "用for輸出"); for(Object str:li) {System.out.println(str);} System.out.println("--------------------"); System.out.println( "用迭代器輸出"); Iterator iterator= li.iterator(); while(iterator.hasNext()) {System.out.println(iterator.next());} System.out.println("--------------------"); System.out.println("訪問"); System.out.println("peekFirst:"+li.peekFirst());//getFirst,getLast System.out.println("peekLast:"+li.peekLast()); System.out.println("刪除"); System.out.println(li.removeFirst());//pollFirst,pollLast System.out.println(li.removeLast()); System.out.println("--------------------"); System.out.println("用for輸出"); for(Object str:li) {System.out.println(str);} System.out.println("--------------------"); } }
4.ArrayList
import java.util.ArrayList; import java.util.Iterator; public class Main { public static void main(String []args) { ArrayList list = new ArrayList(); list.add("A");//將指定的元素追加到此列表的尾部 list.add(1,"B");//插入列表的指定位置 list.add("C"); list.add("D"); list.add("E"); //for遍歷 System.out.println("for遍歷"); for(Object element:list) { System.out.println(element); } System.out.println("------------------"); //用迭代器遍歷 //獲取迭代器 System.out.println("迭代器遍歷"); Iterator iterator = list.iterator(); //如果仍有元素可以迭代,則返回 true。 while(iterator.hasNext()) { System.out.println(iterator.next());// 返回迭代的下一個元素。 } System.out.println("------------------"); //刪除元素remove System.out.println("刪除前:"); for(Object element:list) { System.out.println(element); } list.remove(0); list.remove(2); System.out.println("------------------"); System.out.println("刪除後:"); for(Object element:list) { System.out.println(element); } } }
5.HashMap
import java.util.HashMap; public class Main { public static void main(String []args) { HashMap hs = new HashMap<>(); //寫入數據 System.out.println("寫入數據..."); System.out.println("..."); hs.put(1,"華晨宇"); hs.put(2,"周杰倫"); hs.put(3,"劉若英"); hs.put(4,"許嵩"); //讀取數據 System.out.println("讀取數據..."); System.out.println("..."); System.out.println(hs.get(1)); System.out.println(hs.get(2)); System.out.println(hs.get(3)); System.out.println(hs.get(4)); //刪除數據 System.out.println("..."); System.out.println("刪除數據..."); hs.remove(1); System.out.println(hs.get(1)); } }
小結:
集合的實現類多種多樣,但有一點不變,集合的主要作用是存儲對象,操作對象;根據具體實現類的存儲方式和操作性能特點來配合具體的應用場景是集合的正確打開方式。
集合通用性導致的問題
當把一個元素丟進集合後,集合為了更好的通用性,都會編譯成Object類。
導致的問題:
- 不同對象保存到同一指定集合的異常
- 取出集合中元素導致的強制類型轉換異常
什麼是泛型?
參數化類型!!! 什麼是參數化類型??? 將具體的類型(如String,Integer)抽象成參數。
泛型的作用
- 消除了集合中的強制類型轉換,減少異常。
- 指定了對象的限定類型,實現了Java的類型安全。
- 合併代碼。提高重用率。
泛型的表現形式
菱形語法:
List<String> list = new List<>(); Map<Integer , String > = new Map<>();
泛型類
//泛型類 public class Main<T> { private T data; public Main(T data) { this.data=data; } public T getData() { return data; } public static void main(String []args) { Main<Integer> g1 = new Main<Integer>(1222); System.out.println(g1.getData()); Main<Double> g2 = new Main<Double>(1222.1222); System.out.println(g2.getData()); Main<String> g3 = new Main<String>("cat"); System.out.println(g3.getData()); } }

泛型方法
public class Main { public static <E> void printArray(E inputArray[]) { for(E element:inputArray) { System.out.printf("%s",element); } } public static void main(String args[]) { Integer intArray[]= {1,2,3,4,5}; Double doubleArray[]= {1.1,2.2,3.3,4.4,5.5}; Character charArray[]= {'A','B','C'}; System.out.printf("整型數組為:n"); printArray(intArray); System.out.printf("n"); System.out.printf("雙精度數組為:n"); printArray(doubleArray); System.out.printf("n"); System.out.printf("字符型數組為:n"); printArray(charArray); System.out.printf("n"); } }

泛型接口
public interface TestInterface<T> { public T next(); }
import java.util.Random; public class Main implements TestInterface<String> { String list[]={"L","A","C"}; @Override public String next() { Random rand = new Random(); return list[rand.nextInt(2)]; } public static void main(String[] args) { Main obj = new Main(); System.out.println(obj.next()); } }
