1. 程式人生 > 實用技巧 >Collection集合

Collection集合

1 集合概述: 1.1 什麼是集合?有什麼用? 陣列其實就是一個集合。集合實際上就是一個容器。可以來容納其它型別的資料。 集合為什麼說在開發中使用較多? 集合是一個容器,是一個載體,可以一次容納多個物件。 在實際開發中,假設連線資料庫,資料庫當中有10條記錄。那麼假設把這10條記錄查詢出來,在java程式中會講10條資料封裝成10個java物件, 然後將10個java物件放到某一個集合當中,將集合傳到前端,然後遍歷集合,將一個數據一個數據展現出來。 1.2 集合不能直接儲存基本資料型別,另外集合也不能直接儲存Java物件。 集合當中儲存的都是java物件的記憶體地址。(或者說集合中儲存的是引用。) list.add(100); // 自動裝箱 Integer 注意: 集合在java中本身是一個容器,是一個物件。 集合中任何時候儲存的都是“引用” 1.3 在java中每一個不同的集合,底層會對應不同的資料結構。往不同的集合中儲存元素,等於將資料放到了不同的資料結構當中, 什麼是資料結構?資料儲存的結構就是資料結構。不同的資料結構,資料儲存方式不同。例如: 陣列、二叉樹、連結串列、雜湊表... 以上這些都是常見的資料機構。 你往集合c1中放資料,可能是放到了陣列上了。 你往集合c2中放資料,可能是放到了二叉樹上了。 ...... 你使用不同的集合等同於使用了不同的資料結構。 你在java集合這一章節,你需要掌握的不是精通資料結構。java中已經將資料結構實現了,已經寫好了這些常用的集合類,你只需要掌握怎麼用?在什麼情況下 選擇哪一種合適的集合去使用即可。 new ArrayList(); 建立一個集合,底層是陣列。 new LinkedList(); 建立一個集合物件,底層是連結串列。 new TreeSet(); 建立一個集合物件,底層是二叉樹。 ... 1.4集合在java JDK中哪個包下? java.util.*; 所有的集合類和集合介面都在和hava.util包下。 1.5 為了讓大家掌握集合這塊的內容,最好能將集合的繼承結構圖背會!!! 集合整個這個體系是怎麼樣的一個機構,你需要有印象。 1.6 在java中集合分為兩大類: 一類是單個方式儲存元素: 單個方式儲存元素,這一類集合中的超級父介面:java.util.Collection; 一類是以鍵值對的方式儲存元素 以鍵值對的方式儲存元素,這一類集合中超級父類介面:java.util.Map; 2 總結重點: 第一個重點:把集合繼承結構圖 背會。 第二個重點:把Collection介面中常用方法測試幾遍。 第三個重點:把迭代器弄明白。 第四個重點:Collection介面中的remove方法和contains方法底層都會呼叫equals,把這個弄明白。 集合中儲存的是物件的記憶體地址:

Iterator迭代器原理:(注意:集合物件中儲存的是記憶體地址哦,不是直接儲存的物件或者基本資料型別哦。)

迭代原理:

Collection介面中常用的方法:

package com.javase.Collection;


import java.util.ArrayList;
import java.util.Collection;


/*
關於java.util.Collection介面中常用的方法。
    1 Collection中能存放什麼元素?
        沒有使用“泛型”之前,Collection中可以儲存Object的所有子型別。
        使用了“泛型”之後,Collection中只能儲存某個具體的型別。
        集合後期我們會學習“泛型”語法。目前先不用管。Collection中什麼都可以存,
        只要是Object的子型別就行。(集合中不能直接儲存基本資料型別,也不能存java物件,只是儲存java物件的記憶體地址。)
        
    2 Collection中的常用方法:
        boolean add(Object e) 向集合中新增元素
        int size() 獲取集合中元素的個數。
        void clear() 清空集合
        boolean contains(Object o) 判斷當前集合中是否包含元素o,包含返回true 不包含返回false
        boolean remove(Object o) 刪除集合中的某個元素
        boolean isEmpty() 判斷該集合中元素的個數是否為0
        Object[] toArray() 呼叫這個方法可以吧集合轉換成陣列。(作為了解,使用不多。)
*/ public class CollectionTest01 { public static void main(String[] args) { // 建立一個集合物件 // Collection c = new Collection(); // 介面是抽象的,無法例項化。 // 多型 Collection c = new ArrayList(); // 測試Collection介面中常用的方法 c.add(1200);// 自動裝箱(java5的新特性),實際上是放進去了一個物件的記憶體地址。Integer x = new Integer(1200);
c.add(3.14);// 自動裝箱 c.add(new Object()); c.add(true);// 自動裝箱 // 獲取集合中元素的個數 System.out.println("集合中元素的個數是:" + c.size()); // 4 // 清空集合中的元素 c.clear(); System.out.println("集合中元素的個數是:" + c.size()); // 0 // 在向集合中新增元素 c.add("hello");//
"hello"物件的記憶體地址放到了集合當中。 c.add("world"); c.add("浩克"); c.add("綠巨人"); c.add("1"); // 判斷集合中是否包含"綠巨人" boolean flag = c.contains("綠巨人"); System.out.println(flag); // true boolean flag2 = c.contains("綠巨人2"); System.out.println(flag2); // false // 獲取集合中元素的個數 System.out.println("集合中元素的個數是:" + c.size()); // 5 // 刪除集合中某個元素 c.remove("1"); // 獲取集合中元素的個數 System.out.println("集合中元素的個數是:" + c.size()); // 4 // 判斷集合是否為空(集合中是否存在元素) System.out.println(c.isEmpty()); // false // 清空 c.clear(); System.out.println(c.isEmpty()); // true c.add(100); c.add("abc"); c.add('中'); c.add(true); c.add(new Student()); // 轉換成陣列(使用不多,瞭解一下。) Object[] o = c.toArray(); for (int i = 0; i < o.length; i++) { System.out.print(o[i] + " "); } } } class Student{ public String toString() { return "這是一個Student類"; } }


關於集合遍歷/迭代專題(重點*****)

package com.javase.Collection;


import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;


/*
關於集合遍歷/迭代專題(重點 *****)
*/
public class CollectionTest02 {
    public static void main(String[] args) {
        // 注意:以下講解的遍歷方式/迭代方式,是所有Collection通用的一種方式。
        // 在Map集合中不能用。在所有Collection以及子類中使用。
        // 建立集合物件
        Collection c = new ArrayList(); // 後面的集合無所謂,主要是看前面的Collection介面,怎麼遍歷/迭代
        // 新增元素
        c.add("abc");
        c.add(123);
        c.add(true);
        c.add(new Object());
        c.add('中');
        // 對集合Collection進行遍歷/迭代
        // 第一步:獲取集合物件的迭代器物件Iterator
        Iterator it = c.iterator();
        // 第二步:通過以上獲取的迭代器物件開始迭代/遍歷集合
        
        // Iterator迭代器中的方法
        /*
         boolean hasNext()  如果仍有元素可以迭代,則返回 true。
         Object next()  返回迭代的下一個元素。
         */
        // boolean hasNext = it.hasNext();
        while (it.hasNext()){
            // 不管你當初放進去什麼,取出來統一都是Object。
            Object obj = it.next();
            System.out.println(obj);
        }
    }
}

迭代案例2:

package com.javase.Collection;


import java.util.*;


public class CollectionTest03 {
    public static void main(String[] args) {
        // 建立集合物件
        Collection c1 = new ArrayList(); // ArrayList集合:有序可重複。
        // 新增元素
        c1.add(1);
        c1.add(2);
        c1.add(3);
        c1.add(4);
        c1.add(1);
        
        // 迭代集合
        Iterator t1 = c1.iterator();
        while (t1.hasNext()){
            // 存進去是什麼型別,取出來還是什麼型別。
            Object o = t1.next();
            /*if(o instanceof Integer){
                System.out.println("Integer型別");
            }*/
            // 只不過在輸出的時候會轉換成字串。因為這裡println()會呼叫toString()方法。
            System.out.println(o);
        }
        
        // 建立HashSet集合物件: 無序不可重複
        Collection c2 = new HashSet();
        // 無序:存進去和取出的順序不一定不同。
        // 不可重複: 已經儲存了100了 不能在儲存100了。
        c2.add(100);
        c2.add(200);
        c2.add(300);
        c2.add(400);
        c2.add(500);
        c2.add(600);
        c2.add(700);
        c2.add(800);
        c2.add(900);
        c2.add(100);
        // 迭代集合
        Iterator t2 = c2.iterator();
        while (t2.hasNext()){
            System.out.println(t2.next());
        }
    }
}

Collection中的contains()方法底層原理:

深入Collection集合的contains方法:

package com.javase.Collection;


import java.util.ArrayList;
import java.util.Collection;


/*
深入Collection集合的contains方法:
    boolean contains(Object o)
    判斷集合中是否包含某個物件o
    如果包含返回true 如果不包含返回false
    
    contains 方法是用來判斷集合中是否包含某個元素的方法,
    那麼他在底層是怎麼判斷集合中是否包含某個元素的呢?
        呼叫了equals方法進行比對。
        equals方法返回true,就表示包含這個元素。
*/
public class CollectionTest04 {
    public static void main(String[] args) {
        // 建立集合
        Collection c = new ArrayList();
        
        // 新增元素
        String s1 = new String("abc"); // 0x1111
        c.add(s1);// 放進去了一個"abc"
        
        String s2 = new String("def"); // 0x2222
        c.add(s2);
        
        // 集合中的元素個數
        System.out.println(c.size());
        
        // 新建的物件String
        String x = new String("abc"); // 0x2222
        // c集合中是否包含x?結果猜測一下是true還是false?
        System.out.println(c.contains(x));// 判斷集合中是否存在"abc"  true
    }
}

測試contains方法和remove方法案例:

package com.javase.Collection;



import java.util.ArrayList;
import java.util.Collection;



/*
測試contains方法
測試remove方法。
結論:存放在一個集合中的型別,一定要重寫equals方法。
*/
public class CollectionTest05 {
    public static void main(String[] args) {
        // 建立集合物件
        Collection c = new ArrayList();
        // 建立User物件
        User u1 = new User("jack");
        User u2 = new User("jack");
        // 將物件加到集合中
        c.add(u1);
        //判斷集合中是否包含u2
        
        // 沒有重寫equals方法之前
        // System.out.println(c.contains(u2)); // false
        
        // 重寫equals方法之後,比較的時候會比較name。
        System.out.println(c.contains(u2));//true
        
        c.remove(u2);
        System.out.println(c.size());//0
        
        /*Integer x = new Integer(10000);
        c.add(x);
    
        Integer y = new Integer(10000);
        System.out.println(c.contains(y));//true*/
        
        // Integer 類的 equals方法重寫了。
        // x.equals(y) --> true
        
        // 建立集合物件
        Collection c1 = new ArrayList();
        // 建立字串物件
        String  s1 = new String("hello");
        // 加進去
        c1.add(s1);
        // 建立字串物件
        String  s2 = new String("hello");
        // 刪除s2
        c1.remove(s2);
        // 集合中元素的個數是?
        System.out.println(c1.size());// 0
    }
}



class User{
    private String name;
    
    public User() {
    }
    
    public User(String name) {
        this.name = name;
    }
    
    // 重寫equals方法
    // 將來呼叫equals方法的時候,一定是呼叫這個重寫的equals方法。
    // 這個equals方法的比較原理是:只要姓名一樣就表示同一個使用者。
    public boolean equals(Object o) {
        if(o == null || !(o instanceof User)) return false;
        if(o == this) return true;
        User u = (User)o;
        //如果名字一樣表示同一個人。(不再比較物件的記憶體地址了。比較內容)
        return  u.name.equals(this.name);
    }
}

關於集合元素的remove:

package com.javase.Collection;


import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/*
關於集合元素的remove
    重點:當集合的結構發生改變時,迭代器必須重新獲取,如果還是用以前老的迭代器,會出現異常:java.util.ConcurrentModificationException
    
    重點:在迭代器集合元素的過程中,不能呼叫集合物件的remove方法,刪除元素:
        c.remove(0);迭代過程中不能這樣。
        會出現:java.util.ConcurrentModificationException異常。
        
    重點:在迭代元素過程當中,一定要使用迭代器Iterator的remove方法,刪除元素。不要使用集合自帶的remove方法刪除元素。
*/
public class CollectionTest06 {
    public static void main(String[] args) {
        // 建立集合
        Collection collection = new ArrayList();
        
        // 注意:此時獲取的迭代器,指向的是那時集合中沒有元素狀態下的迭代器。
        // 一定要注意:集合結構只要發生改變,迭代器必須重新獲取。
        // 當集合結構發生了改變,迭代器沒有重新獲取時,呼叫next()方法時:java.util.ConcurrentModificationException
        // Iterator iterator = collection.iterator();
        
        // 新增元素
        collection.add(1);
        collection.add(2);
        collection.add(3);
        // 獲取迭代器
        Iterator iterator = collection.iterator();
        while (iterator.hasNext()){
            // 編寫程式碼時next()返回值型別必須是Object
            // Integer i = iterator.next();
            Object obj = iterator.next();
            System.out.println(obj);
        }
        
        Collection c1 = new ArrayList();
        c1.add("abc");
        c1.add("def");
        c1.add("xyz");
        
        Iterator it1 = c1.iterator();
        while (it1.hasNext()){
            Object o = it1.next();
            // 刪除元素
            // 刪除元素之後,集合的結構發生了變化,應該重新去獲取迭代器。
            // 但是,迴圈下一次的時候並沒有重新獲取迭代器,所以會出現異常。
            // 出異常根本原因:集合中元素刪除了,但是沒有更新迭代器(迭代器不知道集合變化了。)
            // c1.remove(o);//直接通過集合去刪除元素,沒有通知迭代器,(導致迭代器的快照和原集合狀態不同。)
            // System.out.println(o);
            // 使用迭代器來刪除可以嗎?
            // 迭代器去刪除時,會自動更新迭代器,並且更新集合(刪除集合中的元素)。
            it1.remove();// 刪除的一定是迭代器指向的當前元素。
            System.out.println(o);
        }
    
        System.out.println(c1.size());
    }
}