1. 程式人生 > >Java基礎知識(五集合)

Java基礎知識(五集合)

集合是一種特別有用的工具類,可以用於儲存數量不等的多個物件,並可以實現常見的資料結構,如堆疊、佇列等。堆疊(先進後出,後進先出),佇列(先進先出)

在程式設計過程中,通常需要集中存放多個數據。當然可以使用前面學過的陣列來儲存多個數據或者物件,但是陣列的長度不可變化,一旦陣列初始化完成,則長度就固定了下來。如果需要儲存數量變化的資料,陣列就有點無能為了,因此我們需要使用到集合類

Collection介面

這裡寫圖片描述

Collection介面中定義的常用方法:

這裡寫圖片描述

Collection集合的遍歷

1.Iterator介面
Iterator介面是Collection介面的父介面,Iterator介面主要用於遍歷Collection集合中的資料,通常我們也稱為迭代器.

Iterator介面定義的方法

boolean hasNext(); 被迭代的集合元素還沒有被遍歷,則返回true
Object next(); 返回集合裡的下一個元素
void remove(); 刪除集合裡上一次next返回的元素

遍歷方法

Collection list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");

Iterator iterator = list.iterator();
while(iterator.hasNext()){
    String str = (String)iterator.
next(); if(str == "b"){ iterator.remove(); } }

foreach迴圈

當一個數據被放入集合後,資料的型別將被“遺忘”,程式只知道它是一個Object型別的資料,所以我們可以把一個集合類似的看成一個型別為Object的陣列,通過foreach方式進行遍歷

Collection list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");

for(Object obj : list){
    String str = (String)obj;
    System.out.println(str);
}

Collection介面常用的子介面:

1.List介面
2.Queue介面
3.Set介面

List介面

List集合概述:
List代表一個元素有序、可重複的集合,集合中每個元素都有對應的順序索引。
List作為Collection的子介面,可以使用Collection接口裡面的全部方法,而且因為List是有序的元素結構,因此List還增加了一些根據索引來操作集合元素的方法。
List集合拓展的方法:
這裡寫圖片描述

List的常用實現類

ArrayList類
Vector類
Stack類
LinkedList類

ArrayList類
ArrayList類簡介
ArrayList類的底層封裝了一個動態的、允許再分配的Object[]陣列。如果想ArrayList中新增元素超過了陣列的長度時,會重新分配一個長度更長的新陣列
ArrayList拓展的方法:
1.

void ensureCapacity(int minCapacity);

將底層的Object[]陣列長度增加minCapacity,可以通過這個方法一次性增加陣列的長度,減少重新分配的次數,從而提高效能
2.

void trimToSize(); 

調整ArrayList或Vector集合的Object[]陣列長度為當前元素的個數,當集合元素已經確定後,則可以通過這個方法,減少底層陣列的長度,可以減少集合物件所佔用的儲存空間
Vector類
Vector類和ArrayList的用法以及底層原理幾乎一樣,但是由於Vector是一個古老的集合(JDK1.0就存在了),那時候Java還沒有提供系統的集合框架,從JDK1.2以後,Java才提供了系統的集合框架,將Vector改為實現了List介面,從而導致Vector裡有一些功能重複的方法
ArrayList類和Vector類的區別
ArrayList是執行緒不安全的,所以效能會更高;
Vector是執行緒安全的,所以效能會更低;

什麼時候使用ArrayList,什麼時候使用Vector?

1.通常我們都應該選擇使用ArrayList
2.如果在多執行緒的情況下,因為ArrayList是執行緒不安全的,所以可以使用Collections工具類把一個ArrayList變成執行緒安全的集合

Queue介面

1.Queue集合概述
Queue集合用於模擬佇列這種資料結構,即“先進先出(FIFO)”。新元素總是新增到佇列的尾部,訪問元素則會獲得佇列頭部的元素,通常,佇列不允許隨機訪問佇列中的元素

Set介面

Set集合概述:
Set代表一個元素無序、不可重複的集合,如果嘗試把兩個相同的元素新增進同一個Set集合,則會新增失敗,add方法返回false

Set的常用實現類
a.HashSet類
HashSet類簡介:
HashSet是Set介面的典型實現類,大多數時候使用Set集合就是使用這個實現類,
HashSet是根據Hash演算法來儲存集合中的元素,因此具有很好的存取和查詢的效能
注意:
HashSet類判斷兩個物件是否相同的原則,是根據equals和hashCode兩個方法來判斷的;
必須equals方法返回true,並且hashCode方法返回的值相同,HashSet才會把這兩個物件當成是相同的物件,不能重複新增
b.LinkedHashSet類
c.TreeSet類

Set實現類的效能分析

HashSet和TreeSet是Set的兩個典型實現類,HashSet的效能總是比TreeSet要好的,因為TreeSet需要額外的紅黑樹演算法來維護元素的排序,當要對保持元素排序時,才考慮使用TreeSet,否則我們都應該使用HashSet

1.Set集合判斷元素是否為同一個元素的原則,是根據equals方法
2.Set集合的元素可以為null,但是隻能有一個null

Map介面

這裡寫圖片描述
Map介面簡介:
Map是一個可以儲存對映關係資料的集合,因此Map集合裡儲存了兩組值,一組值用於儲存Map的key,另一組陣列用於儲存Map的value。key和value之間存在單向的一對一關係,即通過key總能找到唯一的value。

Map集合的遍歷:

1.遍歷key的方式:

Map map = new HashMap();
map.put(1, 1);
map.put(2, 2);
map.put(3, 3);

Set set = map.keySet();
for(Object obj : set){
    Integer key = (Integer)obj;
    System.out.println("key = " + key + ", value = " + map.get(key));
}

遍歷Entry物件

Map<Integer, Integer> map = new HashMap();
map.put(1, 1);
map.put(2, 2);
map.put(3, 3);

Set<Entry<Integer, Integer>> set = map.entrySet();
for(Entry<Integer, Integer> entry : set){
    System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
}

1.HashMap類和Hashtable類
HashMap和Hashtable類是Map介面的兩種典型實現類,關係類似於ArrayList和Vector之間的關係。Hashtable是一個非常古老的類,而且類名也沒有遵照Java的命名規範,因此我們都應該選擇使用HashMap

HashMap和Hashtable的區別:
1.Hashtable是執行緒安全的,HashMap執行緒不安全,所以HashMap效能要略高。
2.Hashtable的key和value都不能為null,HashMap的key和value則可以為null
這裡寫圖片描述

集合工具類-Collections

Collections簡介:
Collections是一個操作Set、List和Map等集合的工具類,該工具類裡提供了大量方法對集合元素進行排序、查詢和修改等操作

泛型

Java 1.5推出了一個新特性,引數化型別。也就是說所操作的資料型別被指定為一個引數。這種引數型別可以用在類、介面、方法的建立中,好處就是可以在編譯時進行型別檢查,並且所有強制轉換都是自動和隱式的,也提高了程式碼的重用率。引數化型別就是泛型。

泛型在Collection中的運用

Collection<元素型別> c = new ArryList<元素型別>();

表示c集合內只能擺放泛型中所指明的型別,如果擺放其他型別則編譯器會報錯

List<String> list = new ArrayList<String>();
Set<Integer> set = new HashSet<Integer>();
Queue<List<Float>> queue = new LinkedList<List<Float>>();

泛型在Map中的運用
語法:

Map<key的型別, value的型別> map = new HashMap<key的型別, value的型別>();
Map<Integer, String> map = new HashMap<Integer, String>();

Java 7中泛型的新語法
Java 7以後,泛型語法可以更簡單一點:
List list = new ArrayList<>();

深入泛型

泛型介面、類
定義泛型:
public class 類名<泛型名稱1, 泛型名稱2, …>{

}

比如:

public class Dog<T, E, ...>{

}
public class Dog<T>{
    T data;
}

定義泛型後,泛型直接可以作為資料型別來使用

使用泛型類建立物件

public class Dog<T>{
    public T getData(){

    }
}

建立物件:
Dog<String> dog = new Dog<>();
String str = dog.getData();//方法的返回值直接就是String型別,不需要強轉
或者
Dog dog = new Dog();
String str = (String)dog.getData();//如果建立物件時沒有指明泛型的型別,則類中所有泛型就變成了Object

泛型方法

泛型方法和泛型類的區別:
有時候在定義類、介面的時候並沒有定義泛型,但是定義方法時想自己定義泛型,這也是可以的,泛型方法所定義的泛型只能在本方法使用

定義泛型方法:
[修飾符] <泛型名稱1, 泛型名稱2, …> 返回值型別 方法名([形參列表]){
//方法體
}