集合概要學習---粗略

Java Collections Framework是Java提供的對集合進行定義,操做,和管理的包含一組接口,類的體系結構。php

Java集合框架的基本接口/類層次結構:html

java.util.Collection [I]
+--java.util.List [I]
   +--java.util.ArrayList [C]
   +--java.util.LinkedList [C]
   +--java.util.Vector [C]
      +--java.util.Stack [C]
+--java.util.Set [I]
   +--java.util.HashSet [C]
   +--java.util.SortedSet [I]
      +--java.util.TreeSet [C]

java.util.Map [I]
+--java.util.SortedMap [I]
   +--java.util.TreeMap [C]
+--java.util.Hashtable [C]
+--java.util.HashMap [C]
+--java.util.LinkedHashMap [C]
+--java.util.WeakHashMap [C]

其中I表示接口,C表示實現類java

1 List和Set

在實際開發中,須要將使用的對象存儲於特定數據結構的容器中。JDK提供了這樣的容器---集合(Collection)。Collection是一個接口,定義了集合相關的操做方法,其有兩個子接口:List與Setc++

List:可重複集合
Set:不可重複的集合
其中判斷元素是否重複,取決於元素的equals()比較的結果

2 集合持有對象的引用

集合中存儲的都是引用類型元素,而且集合只保存每一個元素對象的引用,而並不是將元素對象自己存入集合。
圖片描述objective-c

3 集合中經常使用的方法:

3.1 add方法

Collection定義了一個add方法用於向集合中添加新元素。
boolean add(E e)
該方法返會將給定的元素添加進集合,若添加成功,則返回true,不然返回false。

實例1c#

import java.util.ArrayList;
import java.util.Collection;
public class Test00{
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<String>();
        System.out.println(c);
        c.add("a");
        c.add("b");
        c.add("c");
        System.out.println(c);
    }
}

3.2 contains方法

boolean contains(Object o)
該方法用於斷定給定的元素是否被包含在集合中。若包含則返回true,反則返回false。
注意:集合在判斷元素是否被包含在集合中是根據每一個元素的equals方法進行比較的結果。
一般有必要重寫equals()保證contains()方法的合理結果

實例2:數組

import java.util.ArrayList;
import java.util.Collection;
public class Test00{
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<String>();
        System.out.println(c);
        c.add("a");
        c.add("b");
        c.add("c");
        System.out.println(c);
        Collection<String> b = new ArrayList<String>();
        b.add("b");
        b.add("c");
        System.out.println(c.contains(b));
        System.out.println(c.contains("b"));
        c.addAll(b);
        System.out.println(c);
        System.out.println(c.contains(b));
        System.out.println(c.contains("h"));
    }
}

3.3 size clear isEmpty

int size()
該方法用於返回當前集合中的元素總數
void clear()
該方法用於清空當前集合。
boolean isEmpty()
該方法用於斷定當前集合中是否不包含任何元素

實例3 :數據結構

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
public class Test00{
    public static void main(String[] args) {
        Collection<String> c = new HashSet<String>();
        System.out.println(c.isEmpty());
        c.add("java");
        c.add("cpp");
        c.add("php");
        c.add("c#");
        c.add("cpp");
        System.out.println("isEmpty : " + c.isEmpty() + ",size : "+ c.size());
        c.clear();// 清空該集合
        System.out.println("isEmpty : "+ c.isEmpty() + ",size : " + c.size());
    }
}

addAll  containsAll
boolean addAll(Collection <? extends E> c)
該方法須要咱們傳入一個集合,並將該集合中的全部元素添加到當前集合中。
boolean containsAll(Collection<?> c)
該方法用於斷定當前結合是否包含給定集合中的全部元素,若包含則返回true。

實例4併發

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
public class Test00{
    public static void main(String[] args) {
        Collection<String> c1 = new ArrayList<String>();
        c1.add("java");
        c1.add("cpp");
        c1.add("php");
        c1.add("c#");
        c1.add("objective-c");
        c1.add("cppc");
        System.out.println(c1);
        Collection<String> c2 = new HashSet<String>();
        c2.addAll(c1);
        System.out.println(c2);
        Collection<String> c3 =new ArrayList<String>();
        c3.add("java");
        c3.add("cpp");
        System.out.println(c1.containsAll(c3));
    }
}

4 Iterator

Iterator是迭代器,擁有兩個方法框架

4.1 hasNext,next方法

迭代器用於遍歷集合元素。獲取迭代器可使用Collection定義的方法:

Iterator iterator()

迭代器Iterator是一個藉口,集合在重寫Collection的iterator()方法時利用內部類提供了迭代器的實現。

Iterator提供了統一的遍歷元素集合的方法,其提供了用於遍歷集合的兩個方法:
boolean hasNext():判斷集合是否還有元素能夠遍歷
E next():返回迭代的下一個元素

實例4

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
public class Test00{
    public static void main(String[] args) {
        Collection<String> c = new HashSet<String>();
        c.add("java");
        c.add("cpp");
        c.add("php");
        c.add("c#");
        c.add("objective-c");
        Iterator<String> iterator = c.iterator();
        while(iterator.hasNext()){
            String str = iterator.next();
            System.out.println(str);
        }
    }
}

4.2 remove方法

在使用迭代器遍歷集合時,不能經過集合的remove方法刪除集合元素,不然會拋出併發更改異常。咱們能夠經過迭代器自身提供的remove()方法來刪除經過next()迭代出的元素

void remove()

迭代器的刪除方法是在原集合中刪除元素。

這裏須要注意的是:在調用remove方法前必須經過迭代器的next方法迭代過的元素,那麼刪除的就是這個元素。而且不可以再次調用remove方法,除非再次調用next()後方可再次調用。

實例5:

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
public class Test00{
    public static void main(String[] args) {
        Collection<String> c = new HashSet<String>();
        c.add("java");
        c.add("cpp");
        c.add("php");
        c.add("c#");
        c.add("objective-c");
        Iterator<String> it = c.iterator();
        while(it.hasNext()){
            String str =  it.next();
            if(str.indexOf("c")!=-1){
                it.remove();// 刪除包含字母c的元素
            }
        }
        System.out.println(c);
    }
}

4.3 加強型for循環

Java5.0以後推出了一個新的特性,加強for循環,也成爲新循環。該循環不通用於傳統循環的工做,其只用於遍歷集合或數組。

語法:
for(元素類型 e:集合或數組){
   循環體
}

實例7

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
public class Test00{
    public static void main(String[] args) {
        Collection<String> c = new HashSet<String>();
        c.add("java");
        c.add("cpp");
        c.add("php");
        c.add("c#");
        c.add("objective-c");
        for(String str : c)
        {
            System.out.print(str.toUpperCase()+" ");
            //C# CPP OBJECTIVE-C JAVA PHP 
        }
    }
}

新循環並不是新的語法,而是在編譯過程當中,編譯器會將新循環轉爲迭代器模式。因此新循環本質上是迭代器。

5 泛型機制

泛型是Java SE5.0引入的特性,泛型的本質是參數化類型。在類、接口、和方法的定義過程當中,所操做的數據類型被傳入的參數指定。

Java泛型機制普遍的應用在集合框架中。全部的集合類型都帶有泛型的參數,這樣在建立集合時能夠指定放入集合中的元素的類型。Java編譯器能夠據此進行類型檢查,這樣能夠減小代碼在運行時出現錯誤的可能性。

圖片描述

6 List

List接口是Collection的子接口,用於定義線性表數據結構。能夠講List理解爲存放對象的數組,只不過其元素能夠動態的增長或減小。
List接口的兩個常見實現類爲ArrayList和LinkList,分別用動態數組和鏈表的方式實現了List接口。
能夠認爲ArrayList和LinkedList的方法在邏輯上徹底同樣,只是在性能上有必定差異。ArrayList更適合於隨機訪問,LinkList更適合於插入和刪除。在性能要求不是特別苛刻的情形下能夠忽略這個差異。

6.1 get和set

List除了繼承Collection定義方法外,還根據其線性表的數據結構定義了一系列的方法,其中最經常使用的就是基於下標的get和set方法

E get(int index)
獲取集合執行下標對應的元素,下標從0開始。
E set(int index,Element)
將給定的元素存入給定位置,並將原位置的元素返回。

實例8

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
public class Test00{
    public static void main(String[] args) {
        List<String> c = new ArrayList<String>();
        c.add("java");
        c.add("cpp");
        c.add("php");
        c.add("c#");
        c.add("objective-c");
        for(int i = 0;i<c.size();i++){
            System.out.println(c.get(i).toUpperCase());
        }
        String value = c.set(1, "c++");
        System.out.println(value);// cpp
        System.out.println(c);// [java, c++, php, c#, objective-c]
        c.set(1,c.set(3, c.get(1)));// 交換1和3上的元素位置  由於內層返回的是3位置的元素
        System.out.println(c);// [java, c#, php, c++, objective-c]
    }
}

6.2 插入和刪除

List根據下標的操做還支持插入語刪除操做

void add(int index,Element);
將給定的元素插入到指定位置,原位置及後續元素都順序向後移動。

E remove(int index);
刪除給定位置的元素,並將被刪除的元素返回。

6.3 List轉換爲數組

List的toArray方法用於將集合轉換爲數組。但實際上該方法是在Collection中定義的,因此全部的集合都具有這個功能。

其有兩個方法:
Object[] toArray()
<T>T[] toArray(T[] a)

其中第二個方法是比較經常使用的,咱們能夠傳入一個指定類型的數組,該數組的元素類型與集合的元素類型一致。返回值則是轉換後的數組,該數組會保存集合中的全部元素。

6.4 數組轉換爲List

Arrays類中提供了一個靜態方法asList,使用該方法咱們能夠將一個數組轉換爲對應的List集合。
其方法定義爲:

static <T>List<T> asList<T... a>

返回的List的集合元素類型由傳入的數組的元素類型決定。
而且要注意的是,返回的集合咱們不能對其增刪元素。而且對集合的元素進行修改hi影響數組對應的元素。

6.5 List排序

Collection.sort方法實現排序
Collection是集合的工具類,它提供了不少便於咱們操做集合的方法,其中就有用於集合排序的sort方法。該方法定義爲:

void sort(List<T> list)
該方法的做用是對給定的集合元素進行天然排序。

6.6 Comparable

Collection的sort方法是對集合元素進行天然排序,那麼兩個元素對象之間就必定要有大小之分。這個代銷之分是如何界定的?

實際上,在使用Collection的sort排序的結合都必須是Comparable接口實現類,該接口表示其子類是可比較的,由於實現該接口必須重寫抽象方法:

int compareTo(T t);
該方法返回值要求:
若o1>o2則返回值應>0
若o1<o2則返回值應<0
若o1=o2則返回值由於0

6.7 LinkedList

雙向鏈表
    雙端效率高

方法

add(數據)    添加數據
get(i)        訪問指定位置的收
remove(i)     移除指定位置的數據
size()        元素的數量
addFirst()    在鏈表首處添加元素
addLast()    在鏈表末尾添加元素
getFirst()    得到第一個元素
getLast()    得到末尾元素
removeFirst()    刪除第一個元素
removeLast()    刪除最後一個元素
iterator()
    輔助建立迭代器對象進行設置

LinkedList實例:

import java.lang.reflect.Array;
    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.Queue;
    
    public class Test00{
        public static void main(String[] args) {
            LinkedList<String> list = new LinkedList<>();
            list.add("aaa");
            list.add("bbb");
            list.add("ccc");
            list.add("ddd");
            list.add("eee");
            list.add("fff");
            list.add("ggg");
            list.add("hhh");
            list.add("iii");
            list.add("jjj");
            list.add("kkk");
            list.add("lll");
                
            System.out.println("獲取鏈表數組的大小: "+list.size());// 獲取鏈表的大小
            System.out.println("get方法獲取元素 "+list.get(0));
            System.out.println("獲取第一個元素"+list.getFirst());
            System.out.println("獲取鏈表的以後一個元素 "+list.getLast());
            
            LinkedList<String> list1 = new LinkedList<>();
            list1.addAll(list);
            for(String s1:list1){// 元素遍歷
                System.out.println(s1);
            }
             // 經過迭代器來遍歷
            Iterator<String> iterator = list.iterator();
            
            if(iterator.hasNext()){
                String str = iterator.next();
                System.out.println(str);
            }
            
            System.out.println("刪除鏈表的第一個元素 "+list.removeFirst());
            System.out.println("刪除鏈表的最後一個元素: "+list.removeLast());
            System.out.println("找到第一個相等的元素進行刪除  "+list.remove("ddd"));
            System.out.println("指定刪除鏈表中的某個元素:"+list.remove(4));
            System.out.println(list.toArray());// 將list鏈表轉爲數組
            Object[] listarr = list.toArray();// 將list轉爲數組,並利用數組的方式進行答應
            System.out.println(Arrays.toString(listarr));
        }
    }

6.8 ArrayList和LinkedList的大體區別以下:

1.ArrayList是實現了基於動態數組的數據結構,LinkedList基於鏈表的數據結構。 
2.對於隨機訪問get和set,ArrayList以爲優於LinkedList,由於LinkedList要移動指針。 
3.對於新增和刪除操做add和remove,LinedList比較佔優點,由於ArrayList要移動數據

示例以下:

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class Test00{
    static final int N = 500000;
    static long timeList(List list){
        long start = System.currentTimeMillis();
        Object o = new Object();
        for(int i = 0;i<N;i++){
            list.add(0,o);
        }
        return System.currentTimeMillis() - start;
        
    }
    
    static long readList(List list){
        long start = System.currentTimeMillis();
        for(int i = 0;i<list.size();i++){
            
        }
        return System.currentTimeMillis() - start;
        
    }
    
    static List addList(List list){
        Object o = new Object();
        for(int i = 0;i<N;i++){
            list.add(0,o);
        }
        return list;
    }
    
    public static void main(String[] args) {
        System.out.println("ArrayList添加"+N+"條耗時:"+timeList(new ArrayList()));
        System.out.println("LinkedList添加"+N+"條耗時"+timeList(new LinkedList()));
        
        List list1 = addList(new ArrayList());
        List list2 = addList(new LinkedList());
        System.out.println("ArrayList查找"+N+"條耗時"+readList(list1));
        System.out.println("LinkedList查找"+N+"條記錄耗時"+timeList(list2));
        /*   結果以下
             ArrayList添加500000條耗時:31141
            LinkedList添加500000條耗時1
            ArrayList查找500000條耗時15
            LinkedList查找500000條記錄耗時3
         */
        
    }
}

7 隊列和棧

7.1 Queue(隊列)

隊列是經常使用的數據結構,能夠將隊列當作特殊的線性表,隊列限制了線性表的訪問方式:只能從線性表
的一端添加(offer)元素,從另外一端取出(poll)元素。

隊列遵循先進先出(FIFO First Input First Output)的原則。

JDK中提供了Queue接口,同時使用LinkedList實現了該接口(選擇LinkList實現Queue的緣由在於
Queue常常要進行添加和刪除的操做,而LinkList在這方面效率較高)。

Queue接口中主要方法以下:

boolean off(E e)     將一個元素添加至隊尾,若是添加成功則返回true。
E poll()             從隊首刪除並返回一個元素。
E peek()            返回隊首的元素(但並不刪除).

7.2 Deque

Deque是Queue的子接口,定義了所謂的"雙端隊列",即從隊列的兩端分別能夠入隊(offer)和出隊(poll),LinkList實現了該接口。
若是將Deque限制爲只能從一端入隊和出隊,則可實現"棧"(Stack)數據結構,對棧而言,入棧稱之爲push,出棧稱之爲pop。
棧遵循先進後出(FILO First Input Last Output)的原則。
圖片描述

import java.util.LinkedList;
import java.util.Queue;
public class Test00{
    public static void main(String[] args) {
        Queue<String> queue = new LinkedList<String>();
        queue.offer("a");// 將一個對象添加至隊尾,若是添加成功則返回true
        queue.offer("b");
        queue.offer("c");
        System.out.println(queue);
        String str =queue.peek();
        System.out.println(str);
        while(queue.size()>0){
            // 從隊首刪除並返回一個元素
            str  = queue.poll();
            System.out.println(str + " ");
        }
        
    }
}

文章參考:http://blog.sina.com.cn/s/blo...

相關文章
相關標籤/搜索