一、Java集合框架概述
1、Collection接口:單列數據,定義了存取一組對象的方法的集合。
- List:元素有序、可重複的集合。
- Set:元素無序、不可重複的集合。
二、使用 Iterator接口遍歷Collection 集合元素
Iterator : Iterator對象稱爲迭代器(設計模式的一種),主要用於遍歷 Collection 集合中的元素。
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* @author hedong
* @version 1.0
* @date 2020/4/9 18:56
*/
public class CollectionTest {
public static void main(String[] args) {
//new一個具體的實現類
Collection c1 = new ArrayList();
//往集合中添加三個數據
c1.add("hedong");
c1.add("zhangsan");
c1.add("liming");
//返回c1的迭代器
Iterator iterator = c1.iterator();
//遍歷集合
while(iterator.hasNext()){//hasNext():判斷是否還有下一個元素
Object obj = iterator.next();//next():指針下移 ,將下移以後集合位置上的元素返回
System.out.println(obj);
}
}
}
注意:hasNext()僅判斷是否還有下一個元素,只有執行了next()指針纔會下移並返回該位置上的元素。
三、foreach遍歷集合和數組
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* @author hedong
* @version 1.0
* @date 2020/4/9 18:56
*/
public class CollectionTest {
public static void main(String[] args) {
//new一個具體的實現類
Collection c1 = new ArrayList();
//往集合中添加三個數據
c1.add("hedong");
c1.add("zhangsan");
c1.add("liming");
//foreach內部任然是使用的iterator實現
//for(要遍歷元素類型 局部變量:需要遍歷的集合對象)
for (Object obj:c1) {
System.out.println(obj);
}
}
}
注意:foreach遍歷方式內部仍然使用Iterator迭代器實現
四、Collection接口的子接口——List接口
List接口是Collection接口的子接口,它包括三個常用實現類:ArrayList、LinkedList和Vector。List集合是有序的,可重複的。
ArrayList和LinkedList的異同: |
二者都線程不安全,相對線程安全的Vector,執行效率高。
此外,ArrayList底層是基於動態數組的數據結構,LinkedList基於鏈表的數據結構。對於
隨機訪問get和set,ArrayList覺得優於LinkedList,因爲LinkedList要移動指針。對於新增
和刪除操作add(特指插入)和remove,LinkedList比較佔優勢,因爲ArrayList要移動數據。
|
ArrayList和Vector的區別: |
Vector和ArrayList幾乎是完全相同的,唯一的區別在於Vector是同步類(synchronized),屬於
強同步類。因此開銷就比ArrayList要大,訪問要慢。正常情況下,大多數的Java程序員使用
ArrayList而不是Vector,因爲同步完全可以由程序員自己來控制。Vector每次擴容請求其大
小的2倍空間,而ArrayList是1.5倍。Vector還有一個子類Stack。
|
五、Collection接口的子接口——Set接口
Set接口是Collection接口的子接口,它包括三個常用實現類:HashSet、LinkedHashSet(HashSet的子類)和TreeSet。Set集合是無序的,不可重複的。
注意:這裏的“無序”不是說每次Set集合打印出來的元素順序都不一樣,而是,每次往Set集合中存放元素時,元素並不是根據底層數組索引順序存放的,存放位置由哈希值決定。同理,List集合中所謂的“有序”是指元素是根據底層數組索引順序存放。也就是說,有序或者無序是針對添加時而言。
- HashSet:Set接口的主要實現類,是線程不安全的,可存儲null值。
- LinkedHashSet:是HashSet的子類,遍歷其內部數據時可按照添加時順序輸出。(注意:這並不意味着“有序”)
- TreeSet:可根據添加對象的指定屬性進行排序。所以TreeSet集合中添加的數據必須爲相同類的對象
添加元素的過程(以HashSet爲例):
1、向HashSet集合中添加元素a
2、調用元素a所在類的hashCode()方法,計算a的哈希值
3、根據計算的哈希值再調用某種算法計算出在HashSet底層數組中的存放位置,即索引位置
4、判斷該位置上是否已經有了元素
- 若該位置沒有其他元素:直接添加元素a成功
- 若該位置已經有了其他元素b:則比較元素a和b的哈希值,若哈希值不相同,則添加元素a成功;若哈希值相同,則調用元素a所在類的equals()方法,若返回true,則添加失敗,返回false,則添加成功。
注意:如果位置上已經有了元素,後面在這個位置上繼續添加的元素將以鏈表方式存儲。
六、Map接口及其多個實現類
Map集合用於存儲雙列數據,即key——value數據。他包括HashMap、LinkedHashMap、TreeMap、Hashtable、Properties多個實現類。
- HashMap:Map的主要實現類,線程不安全、高效,key和value可以爲null。
- LinkedHashMap:HashMap的子類,可以在遍歷Map元素時按照添加時的順序輸出。
- TreeMap:可以進行排序。
- Hashtable:Map古老的實現類,線程安全,效率低,key和value不可以爲null。
- Properties:Hashtable的子類,常用於處理配置文件,key和value都是string類型。
Map結構的理解:
- map中的key:無序的、不可重複的,使用Set存儲key。
- map中的value:無序的,可重複的,使用Collection存儲value。
- map中的Entry:一個鍵值對key—value構成一個Entry對象,無序的,不可重複的,使用Set存儲Entry對象。
HashMap底層實現原理:
實例化Map對象後,底層將創建一個Entry 數組,當添加一個元素(key-value)時,就首先計算元素key的hash值,以此確定插入數組中的位置,如果這個位置沒有元素,則插入成功;如果這個位置已經有了元素,則比較它們的哈希值,如果哈希值不同,則以鏈表的形式鏈在這個元素旁邊;如果哈希值也相同,則調用equals()比較,若爲false,則同樣以鏈表的形式鏈在旁邊,若爲true,則覆蓋它的值。