
jdk的集合框架的主體結構:
接口 |
簡述 |
實現 |
操作特性 |
成員要求 |
Set |
成員不能重復 |
HashSet |
外部無序地遍歷成員。 |
成員可為任意Object子類的對象,但如果覆蓋了equals方法,同時注意修改hashCode方法。 |
TreeSet |
外部有序地遍歷成員;附加實現了SortedSet, 支持子集等要求順序的操作 |
成員要求實現caparable接口,或者使用 Comparator構造TreeSet。成員一般為同一類型。 |
LinkedHashSet |
外部按成員的插入順序遍歷成員 |
成員與HashSet成員類似 |
List |
提供基于索引的對成員的隨機訪問 |
ArrayList |
提供快速的基于索引的成員訪問,對尾部成員的增加和刪除支持較好 |
成員可為任意Object子類的對象 |
LinkedList |
對列表中任何位置的成員的增加和刪除支持較好,但對基于索引的成員訪問支持性能較差 |
成員可為任意Object子類的對象 |
Map |
保存鍵值對成員,基于鍵找值操作,compareTo或compare方法對鍵排序 |
HashMap |
能滿足用戶對Map的通用需求 |
鍵成員可為任意Object子類的對象,但如果覆蓋了equals方法,同時注意修改hashCode方法。 |
TreeMap |
支持對鍵有序地遍歷,使用時建議先用HashMap增加和刪除成員,最后從HashMap生成TreeMap;附加實現了SortedMap接口,支持子Map等要求順序的操作 |
鍵成員要求實現caparable接口,或者使用Comparator構造TreeMap。鍵成員一般為同一類型。 |
LinkedHashMap |
保留鍵的插入順序,用equals 方法檢查鍵和值的相等性 |
成員可為任意Object子類的對象,但如果覆蓋了equals方法,同時注意修改hashCode方法。 |
IdentityHashMap |
使用== 來檢查鍵和值的相等性。 |
成員使用的是嚴格相等 |
WeakHashMap |
其行為依賴于垃圾回收線程,沒有絕對理由則少用 |
|
Java Collections Framework成員主要包括兩種類型,即:Collection和Map類型。 在Java中提供了Collection和Map接口。其中List和Set繼承了Collection接口;同時用Vector、ArrayList、LinkedList三個類實現List接口,HashSet、TreeSet實現Set接口。直接有HashTable、HashMap、TreeMap實現Map接口。Collection----一組獨立的元素,通常這些元素都服從某種規則。List必須保持元素特定的順序,而Set不能有重復元素。 Map----一組成對的“鍵值對”對象,即其元素是成對的對象,最典型的應用就是數據字典,并且還有其它廣泛的應用。另外,Map可以返回其所有鍵組成的Set和其所有值組成的Collection,或其鍵值對組成的Set,并且還可以像數組一樣擴展多維Map,只要讓Map中鍵值對的每個“值”是一個Map即可。Set(interface): 存入Set的每個元素必須是唯一的,因為Set不保存重復元素。加入Set的Object必須定義equals()方法以確保對象的唯一性。Set與Collection有完全一樣的接口。Set接口不保證維護元素的次序。
首先還要說一下迭代器:迭代器是一種設計模式,它是一個對象,它可以遍歷并選擇序列中的對象,而開發人員不需要了解該序列的底層結構。迭代器通常被稱為“輕量級”對象,因為創建它的代價小。
(1) 使用方法iterator()要求容器返回一個Iterator。第一次調用Iterator的next()方法時,它返回序列的第一個元素。
(2) 使用next()獲得序列中的下一個元素。
(3) 使用hasNext()檢查序列中是否還有元素。
(4) 使用remove()將迭代器新返回的元素刪除。
Iterator是Java迭代器最簡單的實現,為List設計的ListIterator具有更多的功能,它可以從兩個方向遍歷List,也可以從List中插入和刪除元素。
壹--Vector
Vector基于Array的List,性能也就不可能超越Array,并且Vector是“sychronized”的,這個也是Vector和ArrayList的唯一的區別。Vector
類可以實現可增長的對象數組。與數組一樣,它包含可以使用整數索引進行訪問的組件。但是,Vector
的大小可以根據需要增大或縮小,以適應創建 Vector
后進行添加或移除項的操作。
用法如下:
package com.zzn.test;
import java.util.Vector;
public class Iterator {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
//Vector的創建
//使用Vector的構造方法進行創建
Vector v = new Vector(4);
//向Vector中添加元素
//使用add方法直接添加元素
v.add("Test0");
v.add("Test1");
v.add("Test2");
v.add("Test3");
v.add("Test4");
//從Vector中刪除元素
v.remove("Test0"); //刪除指定內容的元素
v.remove(0); //按照索引號刪除元素
//獲得Vector中已有元素的個數
int size = v.size();
System.out.println("size:" + size);
//遍歷Vector中的元素
for(int i = 0;i < v.size();i++){
System.out.println(v.get(i));
}
}
}
貳--ArrayList
ArrayList同Vector一樣是一個基于Array的,但是不同的是ArrayList不是同步的。所以在性能上要比Vector優越一些,但是當運行到多線程環境中時,可需要自己在管理線程的同步問題。從其命名中可以看出它是一種類似數組的形式進行存儲,因此它的隨機訪問速度極快,動態的增加和減少元素。
package com.zzn.test;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
/**
* 迭代ArrayList()的4種方法;
*/
public class ArrayListTest {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//方法1
Iterator it1 = list.iterator();
while(it1.hasNext()){
System.out.println(it1.next());
}
//方法2(與方法一大同小異)
for(Iterator it2 = list.iterator();it2.hasNext();){
System.out.println(it2.next());
}
//方法3
for(String tmp:list){
System.out.println(tmp);
}
//方法4
for(int i = 0;i < list.size(); i ++){
System.out.println(list.get(i));
}
}
}
叁--LinkedList:
LinkedList不同于前面兩種List,它不是基于Array的,所以不受Array性能的限制。它每一個節點(Node)都包含兩方面的內容:1.節點本身的數據(data);2.下一個節點的信息(nextNode)。所以
當對LinkedList做添加,刪除動作的時候就不用像基于Array的List一樣,必須進行大量的數據移動。只要更改nextNode的相關信息就可以實現了所以它適合于進行頻繁進行插入和刪除操作。它具有方法addFirst()、addLast()、getFirst()、getLast()、removeFirst()、removeLast(),這些方法(沒有在任何接口或基類中定義過)使得LinkedList可以當作堆棧、隊列和雙向隊列使用。這就是
LinkedList的優勢。Iterator只能對容器進行向前遍歷,而 ListIterator則繼承了Iterator的思想,并提供了對List進行雙向遍歷的方法。
package com.zzn.test;

import java.util.Iterator;
import java.util.LinkedList;

/** *//**
* 迭代ArrayList()的4種方法;
*/

public class LinkedListTest
{
@SuppressWarnings("unchecked")

public static void main(String[] args)
{
LinkedList linkedList = new LinkedList();
linkedList.add("B");
linkedList.add("C");
linkedList.add("D");
linkedList.add("E");
linkedList.add("F");
linkedList.addLast("Z");
linkedList.addFirst("A");
linkedList.add(1, "A2");
System.out.println("Original contents of ll: " + linkedList);

linkedList.remove("F");
linkedList.remove(2);
System.out.println("Contents of ll after deletion: " + linkedList);

linkedList.removeFirst();
linkedList.removeLast();
System.out.println("ll after deleting first and last: " + linkedList);

String val = (String)linkedList.get(2);//第幾個位置
linkedList.set(2, val + "—Changed");
System.out.println("ll after change: " + linkedList);
Iterator iterator = linkedList.iterator();

while(iterator.hasNext())
{
System.out.println(iterator.next());
}
}
}
肆--HashTable
Hashtable繼承Map接口,實現一個key-value映射的哈希表。任何非空(non-null)的對象都可作為key或者value。添加數據使用put(key, value),取出數據使用get(key),這兩個基本操作的時間開銷為常數。
package com.zzn.test;

import java.util.Hashtable;


public class HastTableTest
{

public static void main(String[] args)
{
Hashtable<String, Integer> numbers = new Hashtable<String, Integer>();
numbers.put("one", 1);
numbers.put("two", 2);
numbers.put("three", 3);
Integer n = numbers.get("two");

if (n != null)
{
System.out.println("two = " + n);
}
}
}
伍--HashMap
HashMap把各個Object映射起來,實現了“鍵--值”對應的快速存取。注意,次實現是不同步的。
package com.zzn.test;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class HashMapTest {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
HashMap<String , String> myMap = new HashMap<String , String>();
myMap.put("hello", "你好");
myMap.put("bye", "再見");
myMap.put("thanks", "謝謝");
myMap.put("ok", "好的");
System.out.println("--------------------遍歷key和value----------------------");
for (Iterator iter = myMap.entrySet().iterator();iter.hasNext();){
Map.Entry element = (Map.Entry)iter.next();
Object strKey = element.getKey();
Object strObj = element.getValue();
System.out.println("myMap.get(\""+strKey+"\")="+strObj);
}
System.out.println();
System.out.println("--------------------遍歷整個HashMap----------------------");
Collection objs = myMap.entrySet();
for (Iterator iterator=objs.iterator(); iterator.hasNext();){
Object obj = iterator.next();
System.out.println(obj);
}
System.out.println();
System.out.println("--------------------遍歷HashMap的key----------------------");
Collection keys = myMap.keySet();
for (Iterator iterator=keys.iterator(); iterator.hasNext();){
Object key = iterator.next();
System.out.println(key);
}
System.out.println();
System.out.println("--------------------遍歷HashMap的value----------------------");
Collection values = myMap.values();
for (Iterator iterator=values.iterator(); iterator.hasNext();){
Object value = iterator.next();
System.out.println(value);
}
}
}
陸--TreeMap
package com.zzn.test;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
public class TreeMapTest {
public static void main(String[] args) {
TreeMap tm = new TreeMap();
for (int i = 0; i < 10; i++) {
String a = "key" + i;
String b = "value" + i;
tm.put(a, b);
}
// 第一種方法
// 使用entrySet()方法生成一個由Map.entry對象組成的Set,
// 而Map.entry對象包括了每個元素的"鍵"和"值".這樣就可以用iterator了
Iterator it = tm.entrySet().iterator();
while (it.hasNext()) {
// entry的輸出結果如key0=value0等
Map.Entry entry =(Map.Entry) it.next();
Object key = entry.getKey();
Object value=entry.getValue();
System.out.println(entry);
System.out.println(key);
System.out.println(value);
}
//第二種方法
//這是用TreeMap的keySet()方法,生成的對象是由key對象組成的Set
//再利用TreeMap的get(key)方法,得到對應的value值
Iterator ite = tm.keySet().iterator();
while (ite.hasNext()) {
//it.next()得到的是key,tm.get(key)得到obj
System.out.println(tm.get(ite.next()));
}
}
}
柒--LindedHashMap
LinkedHashMap擴展HashMap,以插入順序將關鍵字/值對添加進鏈接哈希映像中。象LinkedHashSet一樣,LinkedHashMap內部也采用雙重鏈接式列表。
package com.zzn.test;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
public class LinkedHashMapTest {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
LinkedHashMap lHashMap = new LinkedHashMap();
lHashMap.put("One", new Integer(1));
lHashMap.put("Two", new Integer(2));
lHashMap.put("three", new Integer(3));
lHashMap.put("four", new Integer(4));
System.out.println("~~~~~~~~~~~~~~~~~~方法一:迭代LinkedHashMap類型的lHashMap;~~~~~~~~~~~~~~~~~~~~");
for(Iterator it=lHashMap.values().iterator();it.hasNext();){
System.out.println(it.next());
}
System.out.println("~~~~~~~~~~~~~~~~~~方法二:迭代LinkedHashMap類型的lHashMap;~~~~~~~~~~~~~~~~~~~~");
Collection c = lHashMap.values();
Iterator iter = c.iterator();
while (iter.hasNext()){
System.out.println(iter.next());
}
System.out.println("~~~~~~~~~~~~~~~~~~Get Set view of Keys from Java LinkedHashMap;~~~~~~~~~~~~~~~~~~~~");
Iterator itr = lHashMap.keySet().iterator();
while (itr.hasNext()){
System.out.println(itr.next());
}
//key - 要測試其是否在此映射中存在的鍵
boolean blnExistKey = lHashMap.containsKey("Two");
System.out.println(blnExistKey);
//value - 要測試其是否在此映射中存在的值
boolean blnExistValue = lHashMap.containsValue("1");
System.out.println(blnExistValue);
System.out.println("~~~~~~~~~~~~~~~~~~從LinkedHashMap中移除key為“Two”的值;~~~~~~~~~~~~~~~~~~~~");
Object obj = lHashMap.remove("Two");//從LinkedHashMap中移除key為“Two”的值;
System.out.println(obj+ " Removed from LinkedHashMap"); //輸出移除的值;
}
}
捌--HashSet
此類實現 Set 接口,它不保證 set 的迭代順序;特別是它不保證該順序恒久不變。此類為基本操作提供了穩定性能,這些基本操作包括 add、remove、contains 和 size;次實現是不同步的;為快速查找而設計的Set。存入HashSet的對象必須定義hashCode();
package com.zzn.test;
import java.util.HashSet;
import java.util.Iterator;
public class HashSetTest {
@SuppressWarnings("unchecked")
public static void main(String[] args)
{
HashSet hashSet=new HashSet();
String a=new String("A");
String b=new String("B");
String c=new String("B");
String d="D";
hashSet.add(a);
hashSet.add(b);
hashSet.add(d);
System.out.println("~~~~~~~~~~~b和c得值相同;所以size()是3~~~~~~~~~~~");
System.out.println(hashSet.size());
String cz=hashSet.add(c)?"此對象不存在":"已經存在";
System.out.println("測試是否可以添加對象 "+cz);
System.out.println("~~~~~~~~~~~測試是否為空;~~~~~~~~~~~");
System.out.println(hashSet.isEmpty());
System.out.println("~~~~~~~~~~~測試其中是否已經包含某個對象;~~~~~~~~~~~");
System.out.println(hashSet.contains("A"));
System.out.println("~~~~~~~~~~~迭代;~~~~~~~~~~~");
Iterator ir=hashSet.iterator();
while(ir.hasNext())
{
System.out.println(ir.next());
}
System.out.println("~~~~~~~~~~~測試某個對象是否可以刪除;~~~~~~~~~~~");
System.out.println(hashSet.remove("a"));
System.out.println(hashSet.remove("A"));
System.out.println("~~~~~~~~~~~經過測試,如果你想再次使用ir變量,必須重新更新以下;~~~~~~~~~~~");
ir=hashSet.iterator();
while(ir.hasNext())
{
System.out.println(ir.next());
}
}
}
玖--LindedHashSet
具有HashSet的查詢速度,且內部使用鏈表維護元素的順序(插入的次序)。于是在使用迭代器遍歷Set時,結果會按元素插入的次序顯示。
package com.zzn.test;
import java.util.Iterator;
import java.util.LinkedHashSet;
public class LinkedHashSetTest {
public static void main(String[] args) {
LinkedHashSet<Integer> lhashSet = new LinkedHashSet<Integer>();
lhashSet.add(new Integer("1"));
lhashSet.add(new Integer("2"));
lhashSet.add(new Integer("3"));
System.out.println("~~~~~~~~~~~~~~~把LinkedHashSet的所有元素復制到 Object Array中~~~~~~~~~~~~~~~");
Object[] objArray = lhashSet.toArray();
for (Object inte: objArray){
System.out.println(inte);
}
System.out.println("~~~~~~~~~~~~~~~檢查lhashSet中是否存在值為3的元素~~~~~~~~~~~~~~~");
boolean bool = lhashSet.contains(new Integer("3"));
System.out.println(bool);
System.out.println("~~~~~~~~~~~~~~~迭代lhashSet~~~~~~~~~~~~~~~");
for(Iterator it =lhashSet.iterator();it.hasNext();){
System.out.println(it.next());
}
}
}
拾--TreeSet
TreeSet: 保持次序的Set,底層為樹結構。使用它可以從Set中提取有序的序列,TreeSet為使用樹來進行存儲的Set接口提供了一個工具,對象按升序存儲.訪問和檢索是很快的。在存儲了大量的需要進行快速檢索的排序信息的情況下,TreeSet是一個很好的選擇。
package com.zzn.test;
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetTest {
@SuppressWarnings("unchecked")
public static void main(String[] args)
{
System.out.println("~~~~~~~~~~~~~~TreeSet的排序功能~~~~~~~~~~~~~~~");
TreeSet ts = new TreeSet();
ts.add("B");
ts.add("C");
ts.add("A");
ts.add("E");
ts.add("F");
ts.add("D");
//注意如果TreeSet中有重復(一樣的)值,TreeSet會把其他相同的排除掉;
ts.add("A");
System.out.println(ts);
System.out.println("~~~~~~~~~~~~~~TreeSet的迭代~~~~~~~~~~~~~~~");
for(Iterator it =ts.iterator();it.hasNext();){
System.out.println(it.next());
}
}
}
下面說一下他們之間的區別
一、Hashtable和HashMap的區別:
①都屬于Map接口的類,實現了將惟一鍵映射到特定的值上。Hashtable是Dictionary的子類,HashMap是Map接口的一個實現類;
②Hashtable中的方法是同步的,而HashMap中的方法在缺省情況下是非同步的。即是說,在多線程應用程序中,不用專門的操作就安全地可以使用Hashtable了;而對于HashMap,則需要額外的同步機
制。但HashMap的同步問題可通過Collections的一個靜態方法得到解決:Map Collections.synchronizedMap(Map m)這個方法返回一個同步的Map,這個Map封裝了底層的HashMap的所有方法,使得底層
的HashMap即使是在多線程的環境中也是安全的。
③HashMap 類沒有分類或者排序。它允許一個 null 鍵和多個 null 值。Hashtable 類似于 HashMap,但是不允許 null 鍵和 null 值。它也比 HashMap 慢,因為它是同步的。
④HashMap被優先選擇。
二、ArrayList和LinkedList
① ArrayList其實是包裝了一個數組 Object[],當實例化一個ArrayList時,一個數組也被實例化,當向ArrayList中添加對象是,數組的大小也相應的改變。這樣就帶來以下有缺點:
快速隨即訪問 你可以隨即訪問每個元素而不用考慮性能問題,通過調用get(i)方法來訪問下標為i的數組元素。
向其中添加對象速度慢 當你創建數組是并不能確定其容量,所以當改變這個數組時就必須在內存中做很多事情。
操作其中對象的速度慢 當你要想數組中任意兩個元素中間添加對象時,數組需要移動所有后面的對象。
②LinkedList是通過節點直接彼此連接來實現的。每一個節點都包含前一個節點的引用,后一個節點的引用和節點存儲的值。當一個新節點插入時,只需要修改其中保持先后關系的節點的引用即可,
當刪除記錄時也一樣。這樣就帶來以下有缺點:
操作其中對象的速度快 只需要改變連接,新的節點可以在內存中的任何地方
不能隨即訪問 雖然存在get()方法,但是這個方法是通過遍歷接點來定位的所以速度慢。
③當一些被定義好的數據需要放到與數組對應的List中,ArrayList是很好的選擇,因為它可以動態變化,但是不要在整個應用程序用頻繁的使用。當你要很方便的操作其中的數據而不用隨即訪問時
LinkList是很好的選擇。如果你要頻繁隨即訪問建議使用數組。