1. 程式人生 > >黑馬程式設計師——Java基礎->集合框架

黑馬程式設計師——Java基礎->集合框架

——Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! ——-
為什麼出現集合類?
• 面嚮物件語言對事物的體現都是以物件的形式,所以為了方便對多
個物件的操作,就對物件進行儲存,集合就是儲存物件最常用的一
種方式。
陣列和集合類同是容器,有何不同?
• 陣列雖然也可以儲存物件,但長度是固定的;集合長度是可變的。
陣列中可以儲存基本資料型別,集合只能儲存物件。
集合類的特點
• 集合只用於儲存物件,集合長度是可變的。

資料結構:
就是容器中儲存資料的方式。

對於集合容器,有很多種。因為每一個容器的自身特點不同,其實原理在於每個容器的內部資料結構不同。
集合容器在不斷向上抽取過程中。出現了集合體系。
在使用一個體系時,原則:參閱頂層內容。建立底層物件。

集合框架的構成及分類
這裡寫圖片描述

Collection介面:

Collection:
|–List:有序(元素存入集合的順序和取出的順序一致),元素都有索引。元素可以重複。
|–Set:無序(存入和取出順序有可能不一致),不可以儲存重複元素。必須保證元素唯一性。

1,新增:

    add(object):新增一個元素
    addAll(Collection) :新增一個集合中的所有元素。

2,刪除:

    clear():將集合中的元素全刪除,清空集合。
    remove(obj) :刪除集合中指定的物件。注意:刪除成功,集合的長度會改變。
    removeAll(collection)
:刪除部分元素。部分元素和傳入Collection一致。

3,判斷:

    boolean contains(obj) :集合中是否包含指定元素 。
    boolean containsAll(Collection) :集合中是否包含指定的多個元素。
    boolean isEmpty():集合中是否有元素。 

4,獲取:

    int size():集合中有幾個元素。

5,取交集:

    boolean  retainAll(Collection) :對當前集合中保留和指定集合中的相同的元素。如果兩個集合元素相同,返回flase;如果retainAll修改了當前集合,返回true

6,獲取集合中所有元素:

    Iterator  iterator():迭代器

7,將集合變成陣列:

    toArray();

Iterator介面:

迭代器:是一個介面。作用:用於取集合中的元素。
這裡寫圖片描述
每一個集合都有自己的資料結構,都有特定的取出自己內部元素的方式。為了便於操作所有的容器,取出元素。將容器內部的取出方式按照一個統一的規則向外提供,這個規則就是Iterator介面。
也就說,只要通過該介面就可以取出Collection集合中的元素,至於每一個具體的容器依據自己的資料結構,如何實現的具體取出細節,這個不用關心,這樣就降低了取出元素和具體集合的耦合性。

Iterator it = coll.iterator();//獲取容器中的迭代器物件,至於這個物件是是什麼不重要。這物件肯定符合一個規則Iterator介面。

    public static void main(String[] args) {
        Collection coll = new ArrayList();
        coll.add("abc0");
        coll.add("abc1");
        coll.add("abc2");
        //--------------方式1----------------------
        Iterator it = coll.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
        //---------------方式2用此種----------------------
        for(Iterator it = coll.iterator();it.hasNext(); ){
            System.out.println(it.next());
        }
    }

List介面:

List本身是Collection介面的子介面,具備了Collection的所有方法。現在學習List體系特有的共性方法,查閱方法發現List的特有方法都有索引,這是該集合最大的特點。

List:有序(元素存入集合的順序和取出的順序一致),元素都有索引。元素可以重複。
|–ArrayList:底層的資料結構是陣列,執行緒不同步,ArrayList替代了Vector,查詢元素的速度非常快。
|–LinkedList:底層的資料結構是連結串列,執行緒不同步,增刪元素的速度非常快。
|–Vector:底層的資料結構就是陣列,執行緒同步的,Vector無論查詢和增刪都巨慢。

1,新增:

    add(index,element) :在指定的索引位插入元素。
    addAll(index,collection) :在指定的索引位插入一堆元素。

2,刪除:

    remove(index) :刪除指定索引位的元素。 返回被刪的元素。 

3,獲取:

    Object get(index) :通過索引獲取指定元素。
    int indexOf(obj) :獲取指定元素第一次出現的索引位,如果該元素不存在返回-1;
                      所以,通過-1,可以判斷一個元素是否存在。
    int lastIndexOf(Object o) :反向索引指定元素的位置。
    List subList(start,end) :獲取子列表。

4,修改:

    Object set(index,element) :對指定索引位進行元素的修改。

5,獲取所有元素:

    ListIterator listIterator():list集合特有的迭代器。

List集合支援對元素的增、刪、改、查。

List集合因為角標有了自己的獲取元素的方式: 遍歷。

for(int x=0; x<list.size(); x++){
    sop("get:"+list.get(x));
}

在進行list列表元素迭代的時候,如果想要在迭代過程中,想要對元素進行操作的時候,比如滿足條件新增新元素。會發生.ConcurrentModificationException併發修改異常。
導致的原因是:
集合引用和迭代器引用在同時操作元素,通過集合獲取到對應的迭代器後,在迭代中,進行集合引用的元素新增,迭代器並不知道,所以會出現異常情況。
如何解決呢?
既然是在迭代中對元素進行操作,找迭代器的方法最為合適.可是Iterator中只有hasNext,next,remove方法.通過查閱的它的子介面,ListIterator,發現該列表迭代器介面具備了對元素的增、刪、改、查的動作。`

ListIterator是List集合特有的迭代器。
ListIterator it = list.listIterator;//取代Iterator it = list.iterator;
這裡寫圖片描述
這裡寫圖片描述

LinkedList:的特有方法。
addFirst();
addLast();
在jdk1.6以後。
offerFirst();
offerLast();

getFirst():獲取連結串列中的第一個元素。如果連結串列為空,丟擲NoSuchElementException;
getLast();
在jdk1.6以後。
peekFirst();獲取連結串列中的第一個元素。如果連結串列為空,返回null。
peekLast();

removeFirst():獲取連結串列中的第一個元素,但是會刪除連結串列中的第一個元素。如果連結串列為空,丟擲NoSuchElementException
removeLast();
在jdk1.6以後。
pollFirst();獲取連結串列中的第一個元素,但是會刪除連結串列中的第一個元素。如果連結串列為空,返回null。
pollLast();

Set介面:

Set介面中的方法和Collection中方法一致的。Set介面取出方式只有一種,迭代器。

    |--HashSet:底層資料結構是雜湊表,執行緒是不同步的。無序,高效;
    HashSet集合保證元素唯一性:通過元素的hashCode方法,和equals方法完成的。
    當元素的hashCode值相同時,才繼續判斷元素的equals是否為true。
    如果為true,那麼視為相同元素,不存。如果為false,那麼儲存。
    如果hashCode值不同,那麼不判斷equals,從而提高物件比較的速度。
      |--LinkedHashSet:有序,hashset的子類。
    |--TreeSet:對Set集合中的元素的進行指定順序的排序。不同步。TreeSet底層的資料結構就是二叉樹。

雜湊表的原理:
1,對物件元素中的關鍵字(物件中的特有資料),進行雜湊演算法的運算,並得出一個具體的演算法值,這個值 稱為雜湊值。
2,雜湊值就是這個元素的位置。
3,如果雜湊值出現衝突,再次判斷這個關鍵字對應的物件是否相同。如果物件相同,就不儲存,因為元素重複。如果物件不同,就儲存,在原來物件的雜湊值基礎 +1順延。
4,儲存雜湊值的結構,我們稱為雜湊表。
5,既然雜湊表是根據雜湊值儲存的,為了提高效率,最好保證物件的關鍵字是唯一的。
這樣可以儘量少的判斷關鍵字對應的物件是否相同,提高了雜湊表的操作效率。

對於ArrayList集合,判斷元素是否存在,或者刪元素底層依據都是equals方法。
對於HashSet集合,判斷元素是否存在,或者刪除元素,底層依據的是hashCode方法和equals方法。

TreeSet:
用於對Set集合進行元素的指定順序排序,排序需要依據元素自身具備的比較性。
如果元素不具備比較性,在執行時會發生ClassCastException異常。
所以需要元素實現Comparable介面,強制讓元素具備比較性,複寫compareTo方法。
依據compareTo方法的返回值,確定元素在TreeSet資料結構中的位置。
TreeSet方法保證元素唯一性的方式:就是參考比較方法的結果是否為0,如果return 0,視為兩個物件重複,不存。

TreeSet集合排序有兩種方式
Comparable和Comparator區別:
1:讓元素自身具備比較性,需要元素物件實現Comparable介面,覆蓋compareTo方法。
2:讓集合自身具備比較性,需要定義一個實現了Comparator介面的比較器,並覆蓋compare方法,並將該類物件作為實際引數傳遞給TreeSet集合的建構函式。
第二種方式較為靈活。

class Student implements Comparable//該介面強制讓學生具備比較性。
{
    private String name;
    private int age;

    Student(String name,int age)
    {
        this.name = name;
        this.age = age;
    }

    public int compareTo(Object obj)
    {

        //return 0;

        if(!(obj instanceof Student))
            throw new RuntimeException("不是學生物件");
        Student s = (Student)obj;

        System.out.println(this.name+"....compareto....."+s.name);
        if(this.age>s.age)
            return 1;
        if(this.age==s.age)
        {
            return this.name.compareTo(s.name);
        }
        return -1;
        /**/
    }

    public String getName()
    {
        return name;

    }
    public int getAge()
    {
        return age;
    }
}

Map集合:

|–Hashtable:底層是雜湊表資料結構,是執行緒同步的。不可以儲存null鍵,null值。
|–HashMap:底層是雜湊表資料結構,是執行緒不同步的。可以儲存null鍵,null值。替代了Hashtable.
|–TreeMap:底層是二叉樹結構,可以對map集合中的鍵進行指定順序的排序。

把map集合轉成set的方法:
Set keySet();
Set entrySet();//取的是鍵和值的對映關係。

取出map集合中所有元素的方式一:keySet()方法。

    Set keySet = map.keySet();
        Iterator it = keySet.iterator();
        while(it.hasNext()) {
            Object key = it.next();
            Object value = map.get(key);
            System.out.println(key+":"+value);
    }

取出map集合中所有元素的方式二:entrySet()方法。

Set entrySet = map.entrySet();
        Iterator it = entrySet.iterator();
        while(it.hasNext()) {
            Map.Entry  me = (Map.Entry)it.next();
            System.out.println(me.getKey()+"::::"+me.getValue());
        }

使用集合的技巧:
看到Array就是陣列結構,有角標,查詢速度很快。
看到link就是連結串列結構:增刪速度快,而且有特有方法。addFirst; addLast; removeFirst(); removeLast(); getFirst();getLast();
看到hash就是雜湊表,就要想要雜湊值,就要想到唯一性,就要想到存入到該結構的中的元素必須覆蓋hashCode,equals方法。
看到tree就是二叉樹,就要想到排序,就想要用到比較。
比較的兩種方式:
一個是Comparable:覆蓋compareTo方法;
一個是Comparator:覆蓋compare方法。
LinkedHashSet,LinkedHashMap:這兩個集合可以保證雜湊表有存入順序和取出順序一致,保證雜湊表有序。

集合什麼時候用?
當儲存的是一個元素時,就用Collection。當儲存物件之間存在著對映關係時,就使用Map集合。

Collections:

它的出現給集合操作提供了更多的功能。這個類不需要建立物件,內部提供的都是靜態方法。

靜態方法:

Collections.sort(list);//list集合進行元素的自然順序排序。
Collections.sort(list,new ComparatorByLen());//按指定的比較器方法排序。
class ComparatorByLen implements Comparator<String>{
    public int compare(String s1,String s2){
        int temp = s1.length()-s2.length();
        return temp==0?s1.compareTo(s2):temp;
    }
}
Collections.max(list); //返回list中字典順序最大的元素。
int index = Collections.binarySearch(list,"zz");//二分查詢,返回角標。
Collections.reverseOrder();//逆向反轉排序。
Collections.shuffle(list);//隨機對list中的元素進行位置的置換。

Collection 和 Collections的區別:
Collections是個java.util下的類,是針對集合類的一個工具類,提供一系列靜態方法,實現對集合的查詢、排序、替換、執行緒安全化(將非同步的集合轉換成同步的)等操作。
Collection是個java.util下的介面,它是各種集合結構的父介面,繼承於它的介面主要有Set和List,提供了關於集合的一些操作,如插入、刪除、判斷一個元素是否其成員、遍歷等。

Arrays:

用於運算元組物件的工具類,裡面都是靜態方法。
asList方法:將陣列轉換成list集合。

String[] arr = {"abc","kk","qq"};
List<String> list = Arrays.asList(arr);//將arr陣列轉成list集合。

將陣列轉換成集合,有什麼好處呢?用aslist方法,將陣列變成集合;
可以通過list集合中的方法來運算元組中的元素:isEmpty()、contains、indexOf、set;

集合變陣列:用的是Collection介面中的方法:toArray();

將集合變成陣列後有什麼好處?限定了對集合中的元素進行增刪操作,只要獲取這些元素即可。