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

Java之集合初探(一)

lin 數據改變 排序。 方法 規則 找不到 集合 回收 for循環

一、集合概述、區別

集合是一種容器,數組也是一種容器

在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允許重復。

Java之集合初探(一)