關于java集合的的彙總,軒成筆記
1 Java集合簡介
Java是一門面向對象的語言,就免不了處理對象,為了友善操作多個對象,那麼我們就得把這多個對象存儲起來,想要存儲多個對象(變量),很容易就能想到一個容器(集合)來裝載
簡單來說集合就是“由若幹個确定的元素所構成的整體”。就是Java給我們提供了工具友善我們去操作多個Java對象。
- 1.集合隻能存放對象。比如你存入一個int型資料66放入集合中,其實它是自動轉換成Integer類後存入的,Java中每一種基本資料類型都有對應的引用類型。
- 2.集合存放的都是對象的引用,而非對象本身。是以我們稱集合中的對象就是集合中對象的引用。對象本身還是放在堆記憶體中。
- 3.集合可以存放不同類型,不限數量的資料類型。
1.1 如何學習集合
首先需要了解集合的分類,以及集合用法(看api),實作類,各有什麼功能和不同,這在面試中經常會考到,再一個就是從資料結構層面底層去考慮這些問題,雖然以後在工作中多數人都不會涉及,但是這是考驗學習能力的一種方式。
1.2 集合的主要三種類型
- List:一種有序清單的集合,例如,按索引排列的Student的List;
- Set:一種保證沒有重複元素的集合,例如,所有無重複名稱的Student的Set;
- Map:一種通過鍵值(key-value)查找的映射表集合,例如,根據Student的name查找對應Student的Map。
1.2 關于使用集合的心得
- 如果是集合類型,有List和Set供我們選擇。List的特點是插入有序的,元素是可重複的。Set的特點是插入無序的,元素不可重複的。至于選擇哪個實作類來作為我們的存儲容器,我們就得看具體的應用場景。是希望可重複的就得用List,選擇List下常見的子類。是希望不可重複,選擇Set下常見的子類。
- 如果是Key-Value型,那我們會選擇Map。如果要保持插入順序的,我們可以選擇LinkedHashMap,如果不需要則選擇HashMap,如果要排序則選擇TreeMap。
常見的資料結構
資料結構指的是資料的組存儲方式,不同的資料結構有不同的特點。
- 數組結構(ArrayList底層結構) 查詢快,增删慢
- 連結清單結構(LinkedList底層結構) 查詢慢,增删快
- 棧和隊列 棧:先進後出(子彈夾,杯子) 隊列:先進先出(排隊,管子)
棧和隊列

棧和隊列
樹
樹
連結清單
連結清單
2 集合的分類
2.1.常用集合的歸納:
List 接口:元素按進入先後有序儲存,可重複
- LinkedList 接口實作類, 連結清單, 插入删除, 沒有同步, 線程不安全
- ArrayList 接口實作類, 數組, 随機通路, 沒有同步, 線程不安全
- Vector 接口實作類 數組, 同步, 線程安全(Stack 是Vector類的實作類)
Set 接口: 僅接收一次,不可重複,并做内部排序
- HashSet 使用hash表(數組)存儲元素
- LinkedHashSet 連結清單維護元素的插入次序
- TreeSet 底層實作為二叉樹,元素排好序
2.2.最主要是看圖:
常見面試筆試題:Arraylist,LinkedList,Vector的差別![]()
java集合彙總,看這篇就夠了!
集合與數組的差別
數組和集合的差別:
- 1:長度的差別
- 數組的長度固定
- 集合的長度可變
- 2:内容不容
- 數組存儲的是同一種類型的元素
- 集合可以存儲不同類型的元素(但是一般我們不這樣幹..)
- 3:元素的資料類型
- 數組可以存儲基本資料類型,也可以存儲引用類型
- 集合隻能存儲引用類型(你存儲的是簡單的int,它會自動裝箱成Integer)
3.Collection
Collection常見方法
-
添加功能 boolean add(E e) 添加一個元素 boolean addAll(Collection c)
添加一批元素
- 删除功能 boolean remove(Object o) 删除一個元素
-
判斷功能 boolean contains(Object o) 判斷集合是否包含指定的元素 boolean isEmpty()
判斷集合是否為空(集合中沒有元素)
-
擷取功能 int size()
擷取集合的長度
- 轉換功能 Object[] toArray() 把集合轉換為數組
Collection:使用技巧
3.1 list和set的差別:
list和set的差別:
3.2 list
- ArrayList:底層資料結構是數組,查詢快,增删慢,線程不安全,效率高,可以存儲重複元素
- LinkedList 底層資料結構是連結清單,查詢慢,增删快,線程不安全,效率高,可以存儲重複元素
- Vector:底層資料結構是數組,查詢快,增删慢,線程安全,效率低,可以存儲重複元素
list
list常見方法
1.add(int index, Object ele)
2.boolean addAll(int index, Collection eles)
3.Object get(int index)
4.int indexOf(Object obj)
5.int lastIndexOf(Object obj)
6.Object remove(int index)
7.Object set(int index, Object ele)
8.List subList(int fromIndex, int toIndex)
3.3 set集合
Set集合的特點是:元素不可重複
- HashSet集合
- 底層資料結構是哈希表(是一個元素為連結清單的數組)
- 不能保證元素的順序。
- HashSet不是線程同步的,如果多線程操作HashSet集合,則應通過代碼來保證其同步。
- 集合元素值可以是null。
- 影響哈希沖突的條件,首先看哈希值是否相等,然後判斷equals是否相等(内容是否相等)
- TreeSet集合
- A:底層資料結構是紅黑樹(是一個自平衡的二叉樹)
- B:保證元素的排序方式(自然排序),實作Comparable接口
- LinkedHashSet集合
- A::底層資料結構由哈希表和連結清單組成。
- 原來存儲是什麼順序,就是什麼順序
各Set實作類的性能分析
- HashSet的性能比TreeSet的性能好(特别是添加,查詢元素時),因為TreeSet需要額外的紅黑樹算法維護元素的次序,如果需要一個保持排序的Set時才用TreeSet,否則應該使用HashSet。
- LinkedHashSet是HashSet的子類,由于需要連結清單維護元素的順序,是以插入和删除操作比HashSet要慢,但周遊比HashSet快。
- EnumSet是所有Set實作類中性能最好的,但它隻能 儲存同一個枚舉類的枚舉值作為集合元素。
- 以上幾個Set實作類都是線程不安全的,如果多線程通路,必須手動保證集合的同步性,這在後面的章節中會講到。
3.4周遊Collection集合的方式
1.普通的for循環【必須要有索引,可以修改元素】
- 注意set集合是無序的不能使用普通for循環周遊,隻能使用增強for或者疊代器周遊
import java.util.*;
public class test{
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("Hello"); list.add("Java"); list.add("World"); list.add("軒成筆記"); for (int i = ; i < list.size(); i++){ String s = (String) list.get(i); System.out.println(s); } } }
2.疊代器周遊【任何集合都可以周遊,隻能擷取元素】
- 隻要是Collection集合都适合
- 它是Java集合的頂層接口(不包括map系列的集合,Map接口是map系列集合的頂層接口)
1. Object next():傳回疊代器剛越過的元素的引用,傳回值是Object,需要強制轉換成自己需要的類型。
2. boolean hasNext():判斷容器内是否還有可供通路的元素。
3. void remove():删除疊代器剛越過的元素。
- 是以除了map系列的集合,我麼都能通過疊代器來對集合中的元素進行周遊。
- 注意:我們可以在源碼中追溯到集合的頂層接口,比如Collection接口,可以看到它繼承的是類Iterable
import java.util.*;
public class test{
public static void main(String[] args) {
Collection<String> c = new ArrayList<String>();
c.add("Hello"); c.add("Java"); c.add("World"); c.add("軒成筆記"); //擷取疊代器對象 Iterator<String> it = c.iterator(); //hasNext()判斷是否有下一個元素,如果有就用next()擷取 while(it.hasNext()){ //擷取下一個元素 String s = it.next(); System.out.println(s); } } }
3.進階for循環【就是疊代器的簡化方式】
import java.util.*;
public class test{
public static void main(String[] args) {
Collection<String> c = new HashSet<String>();
c.add("Hello"); c.add("Java"); c.add("World"); c.add("軒成筆記"); //進階for周遊集合 for (String s : c){ System.out.println(s); } int[] arr = {, , , , }; //進階for周遊數組 for (int a : arr){ System.out.println(a); } } }
4.1 Map詳解:
- Map用于儲存具有映射關系的資料,Map裡儲存着兩組資料:key和value,它們都可以使任何引用類型的資料,但key不能重複。是以通過指定的key就可以取出對應的value
- Collection中的集合,元素是孤立存在的(了解為單身),向集合中存儲元素采用一個個元素的方式存儲。 Map中的集合,元素是成對存在的(了解為夫妻)。每個元素由鍵與值兩部分組成,通過鍵可以找對所對應的 值。
- Collection中的集合稱為單列集合,Map 中的集合稱為雙列集合。需要注意的是, Map中的集合不能包含重複的鍵, 值可以重複;每個鍵隻能對應一個值。
map圖解
4.2 map主要方法
4.3 HashMap和HashTable的比較:
HashMap和HashTable的比較
4.4 TreeMap
TreeMap
4.4 map小結
- HashMap 非線程安全
- HashMap:基于哈希表實作。使用HashMap要求添加的鍵類明确定義了hashCode()和equals()[可以重寫hashCode()和equals()],為了優化HashMap空間的使用,您可以調優初始容量和負載因子。
- TreeMap:非線程安全基于紅黑樹實作。TreeMap沒有調優選項,因為該樹總處于平衡狀态。
4.5 map各類實用場景
HashMap和HashTable:HashMap去掉了HashTable的contains方法,但是加上了containsValue()和containsKey()方法。HashTable同步的,而HashMap是非同步的,效率上比HashTable要高。HashMap允許空鍵值,而HashTable不允許。
HashMap:适用于Map中插入、删除和定位元素。 Treemap:适用于按自然順序或自定義順序周遊鍵(key)。
map的兩種周遊方式KeySet、entrySet
1. Map集合的第一 種周遊方式:通過鍵找值的方式
方法: Set keySet() 傳回此地圖中包含的鍵的Set視圖。 實作步驟:
- 使用keySet() ,把Map集合中的所有的key取出來,存入到一-個Set集合中
- 周遊set集合,擷取到Map集合中的每一 個key
- 通過Map集合中的V get(0bject key), 擷取到所有的Value值,輸出
public class MapTest02 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map. put( "趙麗穎", );
map. put("楊穎" ,);
map. put("林志穎" ,); Set<String> Set = map.keySet();//傳回的是一個set集合 for (String key : Set) { Integer value = map.get(key); System.out.println(key+" "+value); } } }
2.Map集合的第二種周遊方式: 使用Entry 對象周遊
- Entry:鍵值對(key-value)
- 方法:
- Map接口:
- Set<Map. Entry<K, V>> entrySet() 傳回此地圖中包含的映射的Set視圖。
- java. util Interface Map. Entry<K, V>:
- K getKey()傳回與此條目相對應的鍵。
- V getValue() 傳回與此條目相對應的值。
- 實作步驟:
- 使用Map集合中的entrySet()方法,把集合中多個Entry對象取出來,存儲到一個Set 集合中
- 周遊Set集合,擷取到每一個Entry
- 調用Entry中的getKey()和IgetValue()方法擷取鍵和值
public class MapTest03 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map. put( "趙麗穎", );
map. put("楊穎" ,);
map. put("林志穎" ,); Set<Map.Entry<String, Integer>> set = map.entrySet(); for (Map.Entry<String, Integer> entry : set) { System.out.println(entry.getKey()+entry.getValue()); } } }
制作者:軒成筆記
本文使用 mdnice 排版