1. 程式人生 > 其它 >Java之集合初探(一)

Java之集合初探(一)

一、集合概述、區別

集合是一種容器,陣列也是一種容器

在Java程式設計中,裝各種各樣的物件(引用型別)的叫做容器。

為什麼出現集合類?

面嚮物件語言對事物的體現都是以物件的形式,所以為了方便對多個物件的操作,Java就提供了集合類。

陣列和集合類同是容器,有何不同?

A:長度區別   陣列的長度固定   集合長度可變 B:內容不同   陣列儲存的是同一種類型的元素   而集合可以儲存不同型別的元素 C:元素的資料型別問題   陣列可以儲存基本資料型別,也可以儲存引用資料型別   集合只能儲存引用型別

集合類的特點

集合只用於儲存物件,集合長度是可變的,集合可以儲存不同型別的物件。

如果我們用陣列來製作一個簡單的容器,可以儲存資料改變大小

//自定義的容器

package util;

import java.lang.reflect.Array;
import java.util.Arrays;

public class Myarr {
    private Object[] obj;
    private int size;//代表陣列中有效的數量
    
    public Myarr(){
        obj=new Object[10];
        size=0;
    }
    
    public int Size(){
        return this.size;
    }
    
    public boolean add(Object o){//可以新增各種型別
        //因為陣列的長度是固定的,首先判斷裝滿否
        
        if(size<obj.length){//有效長度小於陣列長度,沒裝滿
            obj[size]=o;
        }else{
            Object[] os=Arrays.copyOf(obj, size+1);
            os[size]=o;
            obj=os;
        }
        size++;
        if(size==obj.length){
            return true;
        }
        return false;
    }
    
    public String toString(){
        Object[] onew=new Object[size];
        for(int i=0;i<size;i++){
            onew[i]=obj[i];
        }
        return Arrays.toString(onew);
    }
}
//主方法
package test;

import util.Myarr;

public class Test {
    public static void main(String[] args) {
                // 新增小於10的情況
        Myarr ma=new Myarr();
        ma.add(56);
        ma.add("so");
        ma.add(5.653);
        System.out.println(ma.Size());
        System.out.println(ma);
                //新增大於10的情況
        Myarr ma1=new Myarr();
        ma1.add(56);
        ma1.add("so");
        ma1.add(5.653);
        ma1.add(56);
        ma1.add("so");
        ma1.add(5.653);
        ma1.add(56);
        ma1.add("so");
        ma1.add(5.653);
        ma1.add(56);
        ma1.add("so");
        ma1.add(5.653);
        System.out.println(ma1.Size());
        System.out.println(ma1);
    }
}

二、不同的集合類

集合是儲存多個元的,由於儲存多個元素我們也是有不同需求的:比如,我要這多個元素中不能有相同的元素,再比如,我要這多個元素按照某種規則排序一下。針對不同的需求,Java就提供了不同的集合類。 這多個集合類的資料結構不同,結構不同不重要的,重要的是你要能夠儲存東西,並且還要能夠使用這些東西,比如說判斷,獲取等。 既然這樣,那麼,這多個集合類是有共性的內容的,我們把這些集合類的共性內容不斷的向上提取,最終就能形成集合的繼承體系結構

Collection:是集合的頂層介面,它的子體系有重複的,有唯一的,有有序的,有無序的。

Collection   List---(有順序, 可以重複)---下標

    (這裡判斷重複的標準是可以互相equals(引用型別))

    LinkedList(基於連結串列)---(改快,查慢)

    *ArrayList(基於陣列)---(改慢,查快)

  Set---(沒有順序, 不可以重複)

    *HashSet(基於hash碼錶)(必須重寫hashCode()方法)

    TreeSet(基於二叉樹---資料結構)

Map(以鍵值對的方式存在)(鍵不能重複)

  Map<Person.hashCode(), int>

  *HashMap

  TreeMap

Comparable(一個方法(comparaTo))

Iterator(迴圈遍歷, 3個方法)

  返回值boolean hasNext()集合裡有沒有下一個

  返回值Object next()返回下一個物件的例項

  remove() 

  大致如下

  while(hasNext()) {     next()   }

 注意:

介面不可以直接new例項化,new後面只能是他的子類,Collection裡沒有方法體

Collection的功能概述:

1:新增功能 boolean add(Object obj):新增一個元素 boolean addAll(Collection c):新增一個集合的元素 2:刪除功能 void clear():移除所有元素 boolean remove(Object o):移除一個元素 boolean removeAll(Collection c):移除一個集合的元素(是一個還是所有) 3:判斷功能 boolean contains(Object o):判斷集合中是否包含指定的元素 boolean containsAll(Collection c):判斷集合中是否包含指定的集合元素(是一個還是所有) boolean isEmpty():判斷集合是否為空 4:獲取功能 Iterator<E> iterator()(重點) 5:長度功能 int size():元素的個數 面試題:陣列有沒有length()方法呢?字串有沒有length()方法呢?集合有沒有length()方法呢? 6:交集功能 boolean retainAll(Collection c):兩個集合都有的元素?思考元素去哪了,返回的boolean又是什麼意思呢? 7:把集合轉換為陣列 Object[] toArray()

Java中集合主要分為三類

  • Set(集)
  • List(列表)
  • Map(對映)

List介面(列表):

List的特徵是其元素以線性方式儲存,集合中可以存放重複物件。 

List介面主要實現類包括:

  • ArrayList() : 代表長度可以改變得陣列。可以對元素進行隨機的訪問,向ArrayList()中插入與刪除元素的速度慢。 API中介紹初始容量為10。
  • LinkedList(): 在實現中採用連結串列資料結構。插入和刪除速度快,訪問速度慢。 

對於List的隨機訪問來說,就是隻隨機來檢索位於特定位置的元素。 List 的 get(int index) 方法放回集合中由引數index指定的索引位置的物件,下標從“0” 開始。最基本的兩種檢索集合中的所有物件的方法: 

  1: for迴圈和get()方法: 

  2: 使用 迭代器(Iterator): 

List主要分:

List:最大的特點是有序,它保證維護元素特定的順序。List為Collection添加了許多方法,使得能夠向List中間插入與移除元素(這隻推薦LinkedList使用。)一個List可以生成ListIterator,使用它可以從兩個方向遍歷List,也可以從List中間插入和移除元素。 

ArrayList:由陣列實現。允許對元素進行快速隨機訪問,但是向List中間插入與移除元素的速度很慢。ListIterator只應該用來由後向前遍歷 ArrayList,而不是用來插入和移除元素。因為那比LinkedList開銷要大很多。 

LinkedList :對順序訪問進行了優化,向List中間插入與刪除的佔用並不大。隨機訪問則相對較慢。(使用ArrayList代替。)還具有下列方法:addFirst(), addLast(),getFirst(),getLast(), removeFirst() 和 removeLast(), 這些方法 (沒有在任何介面或基類中定義過)使得LinkedList可以當作堆疊、佇列和雙向佇列使用。

介面的常用方法

add()   新增

remove()    移除

import java.util.ArrayList;
import java.util.Collection;
public class TestColle {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Collection c=new ArrayList();
        c.add(1);
        c.add("hello");
        c.add(new Person());
        System.out.println(c);
        
        c.remove(1);
        c.remove("hello");
        c.remove(new Person());//用new新建立的equls時找不到原來的new 建立的所以移除不了
        System.out.println(c.size());
        System.out.println(c);
    }
}
class Person{
    @Override
    public String toString() {
        return "Person [hi]";
    }
}

List介面其他常用方法

 1 package until;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 public class Test1 {
 7     public static void main(String[] args) {
 8         List li=new ArrayList();
 9         List lis=new ArrayList();
10         
11         for(int i=0;i<5;i++){
12             li.add("string"+i);
13             if(i%2==0){
14                 lis.add("string"+i);
15             }
16         }
17         System.out.println(li);
18         System.out.println(li.get(2));//獲取該索引位置的值
19         System.out.println(li.set(1, "Hello"));//將某個索引的值設定為另一個物件,然後將原來的索引的值返回
20         System.out.println(li);
21         System.out.println(li.remove(4));//刪除物件並將刪除的物件返回
22         System.out.println(li.indexOf("string0"));//返回該物件第一次出現的位置
23         System.out.println(li.lastIndexOf("string0"));//返回該物件最後一次出現的位置
24         System.out.println(li.retainAll(lis));//取二者的交集賦給第一個集合,如果兩個第一個集合改變了返回true
25         System.out.println(li);
26     }
27 }

Map(對映):

Map 是一種把鍵物件和值物件對映的集合,它的每一個元素都包含一對鍵物件和值物件。 Map沒有繼承於Collection介面 從Map集合中檢索元素時,只要給出鍵物件,就會返回對應的值物件。 

Map的執行效率相對低下。 

Map包含:

Map : 維護“鍵值對”的關聯性,使你可以通過“鍵”查詢“值”

HashMap:Map基於散列表的實現。插入和查詢“鍵值對”的開銷是固定的。可以通過構造器設定容量capacity和負載因子load factor,以調整容器的效能。 

LinkedHashMap: 類似於HashMap,但是迭代遍歷它時,取得“鍵值對”的順序是其插入次序,或者是最近最少使用(LRU)的次序。只比HashMap慢一點。而在迭代訪問時發而更快,因為它使用連結串列維護內部次序。 

TreeMap : 基於紅黑樹資料結構的實現。檢視“鍵”或“鍵值對”時,它們會被排序(次序由Comparabel或Comparator決定)。TreeMap的特點在 於,你得到的結果是經過排序的。TreeMap是唯一的帶有subMap()方法的Map,它可以返回一個子樹。 

WeakHashMao :弱鍵(weak key)Map,Map中使用的物件也被允許釋放: 這是為解決特殊問題設計的。如果沒有map之外的引用指向某個“鍵”,則此“鍵”可以被垃圾收集器回收。 

IdentifyHashMap: : 使用==代替equals()對“鍵”作比較的hash map。專為解決特殊問題而設計。

Map介面常用方法

package until;
import java.util.HashMap;
import java.util.Map;

public class Test1 {
    public static void main(String[] args) {
        Map map = new HashMap();
        for (int i = 0; i < 5; i++) {
            map.put(i, new Person("name" + i));//迴圈新增
        }
        System.out.println(map);
        map.put(5, new Person("Xman"));//再次新增
        System.out.println(map);
        map.put(1, new Person("NewMan"));//在已有的鍵上新增替換
        System.out.println(map);
        System.out.println(map.get(5));//獲取指定的鍵的值
        System.out.println(map.remove(0));//刪除鍵的值並返回值
        System.out.println(map.remove(0, "na"));//刪除鍵值,成功返回true
        System.out.println(map.containsKey(4));//判斷是否包含該鍵
        System.out.println(map.containsValue(new Person("name0")));//判斷是否有該值
        System.out.println(map.size());//返回有多少對
        System.out.println(map.isEmpty());//返回是否空
        map.clear();//清空
        System.out.println(map);
        Map map2=new HashMap();
        map2.putAll(map);//新增另一個map集合
        System.out.println(map2);
    }
}

class Person{
    String name;
    public Person(String name) {
        this.name = name;
    }
    
    @Override
    public String toString() {
        return "P ["+ name + "]";
    }
}

Set介面

Set是最簡單的一種集合。集合中的物件不按特定的方式排序,並且沒有重複物件。 Set介面主要實現了兩個實現類:

  HashSet: HashSet類按照雜湊演算法來存取集合中的物件,存取速度比較快 

  TreeSet :TreeSet類實現了SortedSet介面,能夠對集合中的物件進行排序。 

Set具有與Collection完全一樣的介面,因此沒有任何額外的功能。(這是繼承與多型思想的典型應用:表現不同的行為。)Set不儲存重複的元素。 存入Set的每個元素都必須是唯一的,因為Set不儲存重複元素。加入Set的元素必須定義equals()方法以確保物件的唯一性。Set與Collection有完全一樣的介面。Set介面不保證維護元素的次序。 

 HashSet:為快速查詢設計的Set。存入HashSet的物件必須定義hashCode()。 

TreeSet: 儲存次序的Set, 底層為樹結構。使用它可以從Set中提取有序的序列。 

LinkedHashSet:具有HashSet的查詢速度,且內部使用連結串列維護元素的順序(插入的次序)。於是在使用迭代器遍歷Set時,結果會按元素插入的次序顯示。

三、總結與注意

Collection 和 Map 的區別

容器內每個為之所儲存的元素個數不同。

Collection型別者,每個位置只有一個元素。

Map型別者,鍵值對,類似於資料庫。

注意:

1.Collection、List、Set、Map都是介面,不能例項化。繼承自它們的 ArrayList, Vector, HashTable, HashMap是具象class,這些才可被例項化。

2. 如果涉及到堆疊,佇列等操作,應該考慮用List,對於需要快速插入,刪除元素,應該使用LinkedList,如果需要快速隨機訪問元素,應該使用ArrayList。

3. 在除需要排序時使用TreeSet,TreeMap外,都應使用HashSet,HashMap,因為他們 的效率更高。

4. 容器類僅能持有物件引用(指向物件的指標),而不是將物件資訊copy一份至數列某位置。一旦將物件置入容器內,便損失了該物件的型別資訊。

5. 儘量返回介面而非實際的型別,如返回List而非ArrayList,這樣如果以後需要將ArrayList換成LinkedList時,客戶端程式碼不用改變。這就是針對抽象程式設計。

6、Collection沒有get()方法來取得某個元素。只能通過iterator()遍歷元素。

7、List,可以通過get()方法來一次取出一個元素。使用數字來選擇一堆物件中的一個,get(0)...。(add/get)

8、Map用 put(k,v) / get(k),還可以使用containsKey()/containsValue()來檢查其中是否含有某個key/value。HashMap會利用物件的hashCode來快速找到key。

9、Map中元素,可以將key序列、value序列單獨抽取出來。

使用keySet()抽取key序列,將map中的所有keys生成一個Set。

使用values()抽取value序列,將map中的所有values生成一個Collection。

因為,key總是獨一無二的,value允許重複。