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時的地址是不一樣的,因此每次運行結果中,它的順序可能是變化的
		
		//增 add
		col.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)
          移除此列表中指定位置上的元素。
 int size()
          返回此列表中的元素數。
 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類,提供以與自然語言無關的方式來處理文本、日期、數字和消息的類和接口。



import java.text.CollationKey;
import java.text.Collator;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class MySort2 {

	public static void main(String[] args) {
		sort2();//中文排序
		
	}

	
	private static void sort2() {
		TreeMap map = new TreeMap( new MyCmp2() ); //給TreeMap集合外加一個我們自己寫的比較器,由比較器來決定元素的排序方式
		map.put("周平","1002" );
		map.put("周平2", "1112");
		map.put("張軍1", new Employee("Mike",26));
		map.put("張軍2", new Employee("Rose",23));
		
		Set entries = map.entrySet();
		Iterator it = entries.iterator();
		while(it.hasNext()){
			Map.Entry e = (Map.Entry)it.next();
			System.out.println(e.getKey()+","+e.getValue());
		}
	}

}



class MyCmp2 implements Comparator{
	Collator collator = Collator.getInstance();
	@Override
	public int compare(Object o1, Object o2) {
		CollationKey key1 = collator.getCollationKey(o1.toString());
		CollationKey key2 = collator.getCollationKey(o2.toString());
		return key2.compareTo(key1);
	}
}


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。









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章