標籤:java 集合
集合
一、集合的概念
個人理解:說簡單點就類似如,但又遠厲害於數組。數組只能定長、類型單一,而集合則是在數組上面的擴充,放大。集合可以同時放多個類型對象,也就是人們說的元素,且數量可變的。
書面解釋:集合是包含多個對象的簡單對象,所包含的對象稱為元素。集合裡面可以包含任意多個對象,數量可以變化;同時對對象的類型也沒有限制,也就是說集合裡面的所有對象的類型可以相同,也可以不
同。集合:數量不限、類型不限;數組:定長、類型單一。
二、資料存放區結構分類
主要就是看儲存的方式,像數組就是順序儲存,而集合的儲存方式就比較豐富。有:(1)順序儲存 (2)鏈式儲存 (3)樹形儲存(4)散列儲存Hash (5)Map映射儲存
三、集合架構
(實現就是當前使用較多的(運用較多的就是這六中),曆史集合類就是現在不常用的)
1、集合架構中各介面的特點1)Collection介面
是一組允許重複的對象。
Collection介面用於表示任何對象或元素組。想要儘可能以常規方式處理一組元素時,就使用這一介面。
而且裡面還用到了Iterator介面,也就是Iterator迭代器:主要用來枚舉集合中的元素。(看例子就懂了,在杭電a過題的就容易理解點。跟Scanner相似。簡單的可以理解為:將集合中所有的元素都放在迭代器中(一個特寫的容器),然後遍曆裡面所有的內容)
實作類別:LinkedList ArrayList
(至於內部的方法,直接看其實作類別中的方法即可)
例:
import java.util.ArrayList;import java.util.Collection;import java.util.HashSet;import java.util.Iterator;import cn.hncu.bean.Person;public class CollectionDemo {public static void main(String[] args) {//Collection col = new ArrayList();//Collection<Object> col = new ArrayList<Object>();//元素的存放順序和添加是一致的Collection<Object> col = new HashSet<Object>();//元素的存放順序由內部的Hash演算法根據元素的值來決定,對於物件類型如Person對象,每次new時的地址是不一樣的,因此每次運行結果中,它的順序可能是變化的//增 addcol.add(1); //從jdk1.5以後,可以自動封裝col.add(3);col.add(2);col.add(new Person(25,"Jack"));col.add("Java");col.add(2);//添加重複的元素,對於List是可以的,而對於Set是加不進的。 //刪 remove 移除的是元素本身//col.remove(3);//col.remove(2);//改//col.remove(1); col.add(4); //不合理,因為位置變了Object objs[] = col.toArray();col.clear();for(int i=0;i<objs.length;i++){if(objs[i].equals(1)){objs[i]=4;}col.add(objs[i]);}//查(遍曆)//增強for迴圈(forEach語句),只能讀全部,而且沒有下標的概念//for(Object obj: col){//System.out.println(obj);//}//用迭代器Iterator來進行遍曆集合Iterator<Object> it = col.iterator();while(it.hasNext()){Object obj = it.next();if(obj instanceof Person){System.out.println("Object:"+obj);}else if(obj instanceof Integer){System.out.println("int:"+obj);}else{System.out.println("Other:"+obj);}}}}
2)Set介面
繼承Collection,無序但不允許重複。
按照定義,Set介面繼承Collection介面,而且它不允許集合中存在重複項。所有原始方法都是Collection中現成的,沒有引入新方法。具體的Set實作類別依賴添加的對象的equals()方法來檢查等同性。
實作類別:HashSet TreeSet
3)List介面
繼承Collection,有序但允許重複,並引入位置下標。
List介面繼承了Collection介面以定義一個允許重複項的有序集合。該介面不但能夠對列表的一部分進行處理,還添加了面向位置的操作。面向位置的操作包括插入某個元素或Collection的功能,還包括擷取、除去或更改元素的功能。在List中搜尋
元素可以從列表的頭部或尾部開始,如果找到元素,還將報告元素所在的位置。(註:別小看這位置操作功能的添加,有很大的用處,如需要對集合內哪一個(位置)元素進行操作是,他們就束手無策了)
注意:
a)使用List(如ArrayList)時,不會自動調用hashCode()方法。因為在List中,重複了就重複了,不需判斷,保證唯一性。
b)List中添加了下標index的功能,這樣對List的修改可以利用set方法對指定位置的元素直接進行替換,不需要象Set那麼複雜(要轉換成數組才能修改,之後還要轉換回去)。(驗證上面我說的那點了吧)
c)Collection用Iterator迭代器,而List可以用ListIterator列表迭代器。前者只能next(),後者不但包含next()方法,還包含previous()方法。因此,如果要用List做類似書的翻頁功能,不但可以向後翻,還可以向前翻。
實作類別:LinkedList ArrayList
4)Map介面
Map介面不是Collection介面的繼承。而是從自己的用於維護鍵-值關聯的介面階層入手。按定義,該介面描述了從不重複的鍵到值的映射。
可以把這個介面方法分成三組操作:改變、查詢和提供可選視圖。
改變操作允許從映射中添加和除去鍵-值對。鍵和值都可以為null。但是,不能把Map作為一個鍵或值添加給自身。
Map.Entry介面(Entry就是Map介面中的內部類,所以寫成這樣):Map的entrySet()方法返回一個實現Map.Entry介面的對象Set集合,其中每個對象都是底層Map中一個特定的鍵-值對。
這個還是用圖片比較形象,更容易理解
實作類別:TreeMap HashMap
2、實作類別1)ArrayList類和Linkedlist類
使用兩種類的哪一種取決於特定的需要:如果要支援隨機訪問,而不必在除尾部的任何位置插入或除去元素,那麼,ArrayList提供了可選的集合。
但如果要頻繁的從列表的中間位置添加和除去元素,而只要順序的訪問列表元素,那麼LinkedList實現更好。
常用的幾個方法:
boolean |
add(E e) 將指定的元素添加到此列表的尾部。 |
void |
add(int index,E element) 將指定的元素插入此列表中的指定位置。 |
E |
get(int index) 返回此列表中指定位置上的元素。 |
boolean |
isEmpty() 如果此列表中沒有元素,則返回 true |
E |
remove(int index) 移除此列表中指定位置上的元素。 |
E |
set(int index,E element) 用指定的元素替代此列表中指定位置上的元素。 |
註:此外,LinkedList添加了一些處理列表兩端元素的方法,使用這些方法,可以輕鬆地把LinkedList當作一個堆棧、隊列或其它面向端點的資料結構。本身上就可以把LinkedList看做一個堆棧和隊列,至於為什麼可以分為這兩種,注意看你怎麼用裡
面的方法而已。
void |
addFirst(E e) 將指定元素插入此列表的開頭。 |
void |
addLast(E e) 將指定元素添加到此列表的結尾。 |
E |
getFirst() 返回此列表的第一個元素。 |
E |
getLast() 返回此列表的最後一個元素。 |
E |
removeFirst() 移除並返回此列表的第一個元素。 |
E |
removeLast() 移除並返回此列表的最後一個元素。 |
2)HashMap類和TreeMap類
使用兩種類的哪一種取決於特定的需要:在Map中插入、刪除和定位元素,HashMap是最好的選擇。但如果要按順序遍曆鍵,那麼TreeMap會更好。
使用HashMap要求添加的鍵類明確定義了hashCode()實現(助理解:Map.keySet返回的是鍵的Set集合,而Set集合對hashCode實現有限制,因此作為鍵的類也要遵守該限制)。有了TreeMap實現,添加到映射的元素一定是可排序的。
注意:HashMap和TreeMap都實現Cloneable介面。
3)HashSet類和TreeSet類
“集合架構”支援Set介面兩種普通的實現:HashSet和TreeSet。在更多情況下,會使用HashSet儲存重複自由的集合。考慮到效率,添加到HashSet的對象需要採用恰當分配散列碼的方式來實現hashCode()方法。當需要從集合中以有序的方式抽
取元素時,TreeSet實現會有用處。為了能順利進行,添加到TreeSet的元素必須是可排序的。
因為這個用的相對而言不是很多,在加上看多上面兩大類,具體的自己看看API就會了。
四、集合排序1、方法1
java.lang.Comparable介面適用於一個類有自然順序的時候。假定對象集合是同一類型,該介面允許把集合排序成自然順序。
該介面中的int compareTo( T obj )方法: 比較當前執行個體對象與對象obj,如果位於對象obj之前,返回負值;如果兩個對象在排序中位置相同,則返回0;如果位於對象obj後面,則返回正值。
◆該排序方法的實現要點:
讓被放置到容器的對象類實現Comparable介面。由其中所實現的方法compareTo( )決定對象之間的排列順序。
2、方法2
java.util.Comparator介面適用於一個類有自然順序的時候。假定對象集合是同一類型,該介面允許把集合排序成自然順序。
該介面中的compare ( T o1, To2)方法: 比較用來排序的兩個參數。根據第一個參數小於、等於或大於第二個參數分別返回負、零或正整數
◆該排序方法的實現要點:
讓容器在構造時加入比較子對象。
◆中文排序問題:
比較函數對於英文字母與數字等ASCII碼中的字元排序都沒問題,但中文排序則明顯不正確。這主要是Java中使用中文編碼GB2312或GBK時,char型轉換成int型的過程出現了比較大的偏差。這偏差是由compare方法導致的,因此我們可以自己實
現Comparator介面。另外,國際化問題可用Collator類來解決。
java.text.Collator類,提供以與自然語言無關的方式來處理文本、日期、數字和訊息的類和介面。
3、集合排序的應用場合
在JDK1.2中,有14個類實現了Comparable介面,這些類中指定的自然排序如下:
1)BigDecimal,BigInteger,Byte,Double,Float,Integer,Long,Short按數字大小排序
2)Character 按Unicode值的數字大小排序
3)CollationKey 按語言環境敏感的字串排序
4)Date 按年代排序
5)File 按系統特定的路徑名的全限定字元的Unicode值排序
6)ObjectStreamField 按名字中字元的Unicode值排序
7)String 按字串中字元Unicode值排序
註:如果一個類不能或不便於實現java.lang.Comparable介面,則可以用實現比較子Comparator介面的方法提供自己的排序行為。同樣,如果預設Comparable行為滿足不了工程需要,也可以提供自己的Comparator。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
java之 ------ 集合【詳解】