Java是如何存儲元素的(3)—Collection集合存儲數據原理

一、集合概述

(1)什麼是集合?有什麼用?

數組其實就是一個集合,集合實際上就是一個容器,可以來容納其他類型的數據。

(2)集合爲什麼說在開發中使用較多?

集合是一個容器,是一個載體,可以一次容納多個對象,在實際開發中,假設連接數據庫,數據庫當中有10條記錄,那麼假設把這10條記錄查詢出來,在java程序中會將10條數據封裝成10個java對象,然後將10個java對象放到某一個集合當中,將集合傳到前端,然後遍歷集合,將一個數據一個數據展現出來。

(3)集合中存儲的是引用

集合不能直接存儲基本數據類型,另外集合也不能直接存儲java對象,集合當中存儲的都是java對象的內存地址。(或者說集合中存儲的是引用);

	List.add(100);//自動裝箱Integer

注意:集合在java中本身是一個容器,是一個對象,集合在任何時候存儲都是“引用”。

(4)在java中每一個不同的集合,底層會對應不同的數據結構,往不同的集合中存儲元素,等於將數據放到了不同的數據結構當中。

二、集合結構圖

(1)集合的分類

在java中集合分爲兩大類。一類的是Collectioin,另一類的Map

(2)Collection繼承結構圖

(0)List爲有序,可重複,存儲的元素有下標,而Set正好相反,無序、不可重複、沒有下標。

(1) Iterable是一個接口,Collection這個接口繼承了它,當它調用Iterable接口的時候,會返回一個Iterable這個對象,然後通過這個對象可以進行遍歷。

(2)Vector底層採用數組這種數據結構。(這個是線程安全)vector所有的方法都有synchronized修飾,但是效率低,所以這個方法使用就很少。

(3)Hashset底層是HashMap,實際上HashSet集合在new的時候,底層實際上new了一個HashMap集合。向HashSet集合中存儲元素,實際上是存儲到HashMap集合中了。HashMap集合是一個哈希表數據結構。

(4)TreeSet集合底層實際上是TreeMap newTreeSet集合的時候,底層實際上new了一個TreeMap集合。往TreeSet集合中存放數據的時候,實際上是將數據放到TreeMap集合中了。TreeMap集合底層採用了二叉樹數據結構。

(5)SortedSet特點:也是無序不可重複,但是放在它裏面的元素可以自動排序。我們稱爲可排序的集合。放到集合中的元素是自動按照大小順序排序的,

(3)Collection常用方法

(a)

  • boolean
  • add(E e)
  • 確保此集合包含指定的元素(可選操作)。

 

其實集合裏面只能存放的是引用,所以1200是自動裝箱,Integer x= new Integer(1200);add方法裏面存放了x的地址。

(b)獲取集合中元素的個數

  • int
  • size()
  • 返回此集合中的元素數。

(c)清空

 

(d) 判斷集合中是否包含此元素

  • boolean
  • contains(Object o)
  • 如果此集合包含指定的元素,則返回 true 。

我們想一下,這個包含是指的內存地址還是指的是內容?下面我們通過一個例子來展示一下

        /*創建集合對象*/
        Collection c1 = new ArrayList();
        /*往集合中添加元素*/
        String s1 = new String("abc");
        c1.add(s1);
        String s2 = new String("def");
        c1.add(s2);
        String x = new String("abc");
        System.out.println(c1.contains(x));

我們現在把s1,s2兩個對象放入到了c1集合裏面,現在又聲明瞭一個x對象,裏面的內容和s1一樣都是abc,我們現在調用c1的contains方法,判斷c1.contains(x)返回true還是false。

這個的返回值是true,下面是內存圖

contains裏面其實是equals方法,因爲String已經重新寫了Equals方法,所以比較的是內容。

所以contains方法是用來判斷集合中是否包含某個元素的方法。所以在底層的時候用了equals方法。

(e)刪除集合中的某個元素

  • boolean
  • remove(Object o)
  • 從該集合中刪除指定元素的單個實例(如果存在)(可選操作)。

 

 (g)判斷該集合中的元素的個數是否爲0

底層調用的size(紫色代表實例變量)

        /*創建集合對象*/
        Collection c1 = new ArrayList();
        /*往集合中添加元素*/
        String s1 = new String("abc");
        c1.add(s1);
        String s2 = new String("def");
        c1.add(s2);
        String x = new String("abc");
        c1.remove(x);
        System.out.println(c1.size());

判斷現在集合裏面是否還有s1?

沒有了,因爲remove裏面也是調用了equals方法。

(f)將集合轉換爲數組(瞭解)

  • toArray()
  • 返回一個包含此集合中所有元素的數組。

 

 

 很明顯這裏存的是內存地址。

三、Collection集合迭代

注意:以下講解的遍歷/迭代方式,是所有Collection通用的一種方式,在Map集合中不能使用,在所有的Collection以及子類中使用。

(1)首先聲明瞭集合

Collection c1 = new ArrayList();

(2)往集合裏面添加元素

c1.add(100);
c1.add(20);
c1.add("趙曉東");

(3)拿到迭代器

 Iterator i1 = c1.iterator();

(4)對迭代器進行遍歷

 while (i1.hasNext()){
            Object o1 = i1.next();
            System.out.println(o1);
        }

解釋一下,迭代器有兩個重要的方法,一個是hasNext()用來判斷下面是否還有數據,next()是用來獲取的。

四、List

(1)List集合存儲元素特點

有序:List集合中的元素有下標,從0開始,從1遞增。

可重複:存儲一個1,還可以再存儲1.

(2)List常用方法

(a)

  • get(int index)
  • 返回此列表中指定位置的元素。

 (b)在指定位置添加元素

• void    • add(int index, E element) 
    • 將指定的元素插入此列表中的指定位置(可選操作)

 

 我現在用這個方法,往指定元素中添加。

因爲有下標,所以List集合有自己比較特殊的遍歷方式,通過下標遍歷。[List集合特有的方式,Set沒有

因爲有下標,所以List集合有自己比較特殊的遍歷方式,通過下標遍歷。[List集合特有的方式,Set沒有.

(c)修改指定位置元素

  • set(int index, E element)
  • 用指定的元素(可選操作)替換此列表中指定位置的元素。

 

 

 

 (3)ArrayList

1、默認初始化容量爲10

2、集合底層是Object數組

3、集合的size()方法是獲取集合中元素的個數,而不是獲取容量。

4、ArrayList集合的擴容

擴容到原容量的1.5倍。

ArrayList集合儘可能減少擴容

5、優點:檢索效率比較高

缺點:隨機增刪元素效率比較低,另外數組無法存儲大數據量,但是向數組末尾添加元素的效率還是很高的。

6、這麼多集合中,那個集合最多?

ArrayList,因爲一般都在末尾添加元素。檢索效率也比較高。

(4)LinkedList

 

Linkedlist集合有初始化容量嗎?沒有,最初這個鏈表是沒有任何元素。first和last引用都是Null,不管是likedList還是ArrayList,以後寫代碼時不需要關心具體哪個集合,因爲我們面向接口編程,調用的方法都是接口中的方法

 五、Set

(1)HashSet集合,HashSet的遍歷

        Set<String> s1 = new HashSet<>();
        s1.add("嘻嘻");
        s1.add("哈哈哈");
        s1.add("嘻嘻");
        for (String t1 :s1){
            System.out.println(t1);
        }

因爲Set是不可重複的,所以存入兩個“嘻嘻”,會被覆蓋

(2)HashSet

 

        Set<String> s1 = new TreeSet<>();
        s1.add("A");
        s1.add("B");
        s1.add("D");
        s1.add("C");
        for(String t1:s1){
            System.out.println(t1);
        }
A
B
C
D

因爲HashSet可以自動排序。

總結:Collection是一個接口,所以它不能聲明對象,List和Set分別繼承了 它,List裏面有ArrayList和LinkedList還有Vector。Set有HashSet和TreeSet。他們都聲明方式基本相同,遍歷都是通過Iterator進行遍歷,他們添加元素都是一樣的,都是通過add()元素進行添加。其中List可以通過get()獲取元素。然而set是沒有get()方法的,這個和他們的內存有關係,其實List是有下標的,Set沒有下標,這也就決定了是否有get()方法。

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