Java-Collection

一、集合基本特性


1 概述

數組長度是固定,當添加的元素超過了數組的長度時需要對數組重新定義,太麻煩,java內部給我們提供了集合類,能存儲任意對象,長度是可以改變的,隨着元素的增加而增加,隨着元素的減少而減少。

2 數組與集合區別 

(1)數組既可以存儲基本數據類型,又可以存儲引用數據類型,基本數據類型存儲的是值,引用數據類型存儲的是地址值;
        集合只能存儲引用數據類型(對象)集合中也可以存儲基本數據類型,但是在存儲的時候會自動裝箱變成對象
(2)數組長度是固定的,不能自動增長;集合的長度的是可變的,可以根據元素的增加而增長

3 使用場景

如果元素個數是固定的推薦用數組;如果元素個數不是固定的推薦用集合


二 、Java集合框架架構圖


三、Iterator


1 迭代器原理

迭代器是對集合進行遍歷,而每一個集合內部的存儲結構都是不同的,所以每一個集合存和取都是不一樣, 那麼就需要在每一個類中定義hasNext()和next()方法,這樣做是可以的, 但是會讓整個集合體系過於臃腫,迭代器是將這樣的方法向上抽取出接口, 然後在每個類的內部,定義自己迭代方式, 這樣做的好處有二,第一規定了整個集合體系的遍歷方式都是hasNext()和next()方法,第二,代碼有底層內部實現,使用者不用管怎麼實現的,會用即可。

2 常用方法

next()方法返回迭代的下一個元素。
hashNext()如果仍有元素可以迭代返回true。
remove()從迭代器指向的集合中移除最後一個元素。


3 應用場景

(1)併發修改異常產生的原因及解決方案?
 有一個集合,請問,我想判斷裏面有沒有"world"這個元素,如果有,我就添加一個"javaee"元素,請寫代碼實現。
  1. List list = new ArrayList();
  2. list.add("a");
  3. list.add("b");
  4. list.add("world");
  5. list.add("d");
  6. list.add("e");
  7. /*Iterator it = list.iterator();
  8. while(it.hasNext()) {
  9. String str = (String)it.next();
  10. if(str.equals("world")) {
  11. list.add("javaee"); //這裏會拋出ConcurrentModificationException併發修改異常
  12. }
  13. }*/
(2)迭代器遍歷的過程中集合是不允許修改的。
(3)解決方案。
 迭代器遍歷元素的過程中如果需要修改請採用ListIterator(特有功能)。
  1. ListIterator lit = list.listIterator();
  2. //如果想在遍歷的過程中添加元素,可以用ListIterator中的add方法
  3. while(lit.hasNext()) {
  4. String str = (String)lit.next();
  5. if(str.equals("world")) {
  6. lit.add("javaee");
  7. }
  8. }
(4)Enumeration和Iterator接口的區別?

Enumeration的速度是Iterator的兩倍,也使用更少的內存。Enumeration是非常基礎的,也滿足了基礎的需要。但是,與Enumeration相比,Iterator更加安全,因爲當一個集合正在被遍歷的時候,它會阻止其它線程去修改集合。 迭代器取代了Java集合框架中的Enumeration。迭代器允許調用者從集合中移除元素,而Enumeration不能做到。爲了使它的功能更加清晰,迭代器方法名已經經過改善。

4 ListIterator

(1)常用方法
  boolean hashNext()是否有下一個
  Object next() 返回下一個元素
  Object hasPrevious()是否有前一個
  Object previous() 返回上一個元素
...add set 等方法

5  ListIterator與Iterator的區別? 

從以上內容中也可以總結出ListIterator與Iterator的區別:ListIterator遍歷只針對List集合而Iterator遍歷操作是針對所有集合的
Iterator 對集合只能是前向遍歷,ListIterator 既可以前向也可以後向。ListIterator 實現了 Iterator 接口,幷包含其他的功能,比如:增加元素,替換元素,獲取前一個和後一個元素的索引,等等。

四、List集合


1 List集合特點

  1. ArrayList: 底層數據結構是數組,查詢快,增刪慢。線程不安全,效率高。
  2. Vector:底層數據結構是數組,查詢快,增刪慢。 線程安全,效率低。
  3. Vector相對ArrayList查詢慢(線程安全的)
  4. Vector相對LinkedList增刪慢(數組結構)
  5. LinkedList: 底層數據結構是鏈表,查詢慢,增刪快。 線程不安全,效率高。
  6. Vector和ArrayList的區別:
  7. (1)Vector是線程安全的,效率低;ArrayList是線程不安全的,效率高。
  8. (2)共同點:都是數組實現的
  9. ArrayList和LinkedList的區別
  10. (1)ArrayList底層是數組結構,查詢和修改快
  11. (2) LinkedList底層是鏈表結構的,增和刪比較快,查詢和修改比較慢
  12. 共同點:都是線程不安全的
  13. 使用說明:查詢多用ArrayList;增刪多用LinkedList;如果都多ArrayList

2 Vector集合特點

(1)Vector特有功能
  1. public void addElement(E obj)
  2. public E elementAt(int index)
  3. public Enumeration elements()
(2)使用示例
  1. Vector v = new Vector(); //創建集合對象,List的子類
  2. v.addElement("a");
  3. v.addElement("b");
  4. v.addElement("c");
  5. v.addElement("d");
  6. //Vector迭代
  7. Enumeration en = v.elements(); //獲取枚舉
  8. while(en.hasMoreElements()) { //判斷集合中是否有元素
  9. System.out.println(en.nextElement());//獲取集合中的元素
  10. }
(3)Vector不推薦使用的原因?

  Vector所有方法都是同步,有性能損失。
  Vector早期版本出現的。
  Vector初始length是10 超過length時 以100%比率增長,相比於ArrayList更多消耗內存。

五、Set集合(接口)


1 概述

(1)set集合特點無序,不允許重複。常用的實現類有HashSet ,TreeSet。特點見下圖

(2)資料參考:http://blog.csdn.net/zhangweiiou/article/details/48946623

2 HashSet

HashSet原理

(1)HashSet繼承了AbstractSet實現了Set接口,在底層使用HashMap的key進行元素存儲,從而保證了元素的唯一性。

(2)我們使用Set集合都是需要去掉重複元素的, 如果在存儲的時候逐個equals()比較, 效率較低,哈希算法提高了去重複的效率, 降低了使用equals()方法的次數

(3)當HashSet調用add()方法存儲對象的時候, 先調用對象的hashCode()方法得到一個哈希值, 然後在集合中查找是否有哈希值相同的對象,如果沒有哈希值相同的對象就直接存入集合,如果有哈希值相同的對象, 就和哈希值相同的對象逐個進行equals()比較,比較結果爲false就存入, true則不存

將自定義類的對象存入HashSet去重複

類中必須重寫hashCode()和equals()方法

hashCode(): 屬性相同的對象返回值必須相同, 屬性不同的返回值儘量不同(提高效率)

equals(): 屬性相同返回true, 屬性不同返回false,返回false的時候存儲

3 TreeSet

概述:TreeSet是用來排序的, 可以指定一個順序, 對象存入之後會按照指定的順序排列。
用法:
  1. a.自然順序(Comparable)
  2. TreeSet類的add()方法中會把存入的對象提升爲Comparable類型
  3. 調用對象的compareTo()方法和集合中的對象比較
  4. 根據compareTo()方法返回的結果進行存儲
  5. b.比較器順序(Comparator)
  6. 創建TreeSet的時候可以指定 一個Comparator
  7. 如果傳入了Comparator的子類對象, 那麼TreeSet就會按照比較器中的順序排序
  8. add()方法內部會自動調用Comparator接口中compare()方法排序
  9. 調用的對象是compare方法的第一個參數,集合中的對象是compare方法的第二個參數
  10. c.兩種方式的區別
  11. TreeSet構造函數什麼都不傳, 默認按照類中Comparable的順序(沒有就報錯ClassCastException)
  12. TreeSet如果傳入Comparator, 就優先按照Comparator

Comparable接口:
定義:此接口強行對實現它的每個類進行整體排序,此排序稱爲自然排序。實現此接口的對象列表(和數組)可以通過 Collections.sort(和 Arrays.sort)進行自動排序。(默認排序升序)對於類 C 的每一個 e1 和 e2 來說,當且僅當 e1.compareTo(e2) == 0 與 e1.equals(e2) 具有相同的 boolean 值時,類 C 的自然排序才叫做與 equals 一致。注意,null 不是任何類的實例,即使 e.equals(null) 返回 false,e.compareTo(null) 也將拋出 NullPointerException。
方法: compareTo(T o) 比較此對象與指定對象的順序。

Java集合框架中的工具類


1 概述:集合框架中的工具類有Arrays和Collections兩種。

2 Arrays: 此類包含了用來操作數組的各種方法如:搜索,排序。

應用場景之 - 數據與集合的轉換

(1)集合轉數組:
  1. String [] strArr = list.toArray(new String[list.size()]);
(2)數組轉集合:

  1. Integer[]arr = {11,22,33,44,55};
  2. List<Integer> list = Arrays.asList(arr);

3 Collections 操作集合的工具類


集合迭代的三種方式總結


 區別 
(1)普通for循環,可以刪除
(2)迭代器,可以刪除,但是必須使用迭代器自身的remove方法,否則會出現併發修改異常
(3)增強for循環不能刪除
掌握增強for循環的內部實現原理

 for(type element: array)

  {

        System.out.println(element);

  }


集合中的幾個概念


1 集合初始化容量;負載因子;擴充容量說明http://www.cnblogs.com/xiezie/p/5511840.html
負載因子:比如說散列表長度爲m,其中有n個位置已放了值,那麼負載因子 a=n/m。

2 fail-fast 機制是java集合(Collection)中的一種錯誤機制。 fail-fast機制在遍歷一個集合時,當集合結構被修改(同步修改),會拋出Concurrent Modification Exception
解決辦法採用:CopyOnWriteArrayList(類)。對以上內容涉及到的概念進行如下說明:
fail-safe機制:保證任何對集合的修改操作都會在一個複製集合上操作。因此不會拋出ConcurrentModificationException異常。產生兩個問題1)複製集合會產生大量臨時對象,增大系統開銷。2)無法保證讀取的數據是原始數據結構中的數據。
2.1什麼叫同步修改?
當一個線程正在遍歷一個集合時,此時又有另一個線程修改了集合的內容(添加,刪除,或修改)這就叫做同步修改(併發修改)。
2.2fail-fast是如何檢測的?
爲了保證集合在遍歷的過程中不被修改,迭代器內部維護了一個標記“modCount”,當集合發生改變內部標記“modCount”也會發生改變,而迭代器每次在遍歷集合的過程中hashNext()和next()都會檢查這個標記,當發現這個標記發生改變了就會拋出,ConcurrentModificationException異常。





 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章