java中有好多集合:List,ArrayList,Vector,HashSetTreeSet,它們之間的區別,java集合的框架等等總是很模糊,稱有時間總結下。
一、Collection接口和Iterator接口
1.Collection框架:

collection接口主要定義了一些操作集合元素的方法:
|
|
Ensures that this collection contains the specified element (optional operation).如果插入成功,返回true |
|
|
addAll Adds all of the elements in the specified collection to this collection (optional operation).改變返回true |
|
|
clear Removes all of the elements from this collection (optional operation). |
|
|
Returns true if this collection contains the specified element. |
|
|
containsAll Returns true if this collection contains all of the elements in the specified collection. |
|
|
Compares the specified object with this collection for equality. |
|
|
hashCode Returns the hash code value for this collection. |
。。。。。。具體可看文檔
2.使用Iterator接口遍歷幾何元素
Iterrator接口隱藏了各種Collection實現類的細節,向應用程序提供了遍歷Collection集合元素的統一編程接口。Iterator接口里定義了如下三個方法:
Boolean hashNext(): 如果被迭代的集合元素還沒有被遍歷,則返回true.
Object next(): 返回集合里的下一個元素。
Void remove(): 刪除集合里上一次next方法返回的元素。
**當使用Iterator迭代訪問Collection集合元素時,Collection集合里的元素不能被改變,只有通過Iterator的remove方法刪除上一次next方法返回的集合元素才可以;否則將引發java.util.Concurrent ModificationException異常。
下面開始一個個類介紹
二、set集合
Set集合的方法與Collection基本上完全一樣,它沒有提供額外的方法。實際上Set就是Collection,只是行為略有不同(Set不允許包含重復元素)。
Set判斷兩個對象是否相同是根據equals方法。也就是說,只要兩個對象用equals方法方法比較返回false,Set就會接受這兩個對象。
1.HashSet是Set的典型實現,HashSet按Hash算法來存儲集合中的元素,因此具有很好的存取和查找性能。
特點:不能保證元素的排列順序;不是同步的,不是線程安全;集合值可以是null。
HashSet集合判斷兩個元素的相等的標准是兩個對象通過equals方法比較相等,並且兩個對象的hashCode()方法返回值也相等。
示例:
import java.util.*;
//類A的equals方法總是返回true,但沒有重寫其hashCode()方法
class A
{
public boolean equals(Object obj)
{
return true;
}
}
//類B的hashCode()方法總是返回1,但沒有重寫其equals()方法
class B
{
public int hashCode()
{
return 1;
}
}
//類C的hashCode()方法總是返回2,但沒有重寫其equals()方法
class C
{
public int hashCode()
{
return 2;
}
public boolean equals(Object obj)
{
return true;
}
}
public class TestHashSet
{
public static void main(String[] args)
{
HashSet books = new HashSet();
//分別向books集合中添加2個A對象,2個B對象,2個C對象
books.add(new A());
books.add(new A());
books.add(new B());
books.add(new B());
books.add(new C());
books.add(new C());
System.out.println(books);
}
}
輸出:[B@1, B@1, C@2, A@659e0bfd, A@2a139a55]
可以看出HashSet把A,B當成兩個對象,C只有一個。
2.LinkedHashSet類
LinkedHashSet集合同樣是根據元素的hashCode值來決定元素的存儲位置,但是它同時使用鏈表維護元素的次序。這樣使得元素看起 來像是以插入順序保存的,也就是說,當遍歷該集合時候,LinkedHashSet將會以元素的添加順序訪問集合的元素。
LinkedHashSet在迭代訪問Set中的全部元素時,性能比HashSet好,但是插入時性能稍微遜色於HashSet。
import java.util.*;
public class TestLinkedHashSet
{
public static void main(String[] args)
{
LinkedHashSet books = new LinkedHashSet();
books.add("第一個");
books.add("第二個");
//刪除 Struts2權威指南
books.remove("第一個");
//重新添加 Struts2權威指南
books.add("第一個");
System.out.println(books);//[第二個, 第一個]
}
}
輸出:[第二個, 第一個] 可以看到順序是按插入順序排列的。
3.TreeSet類
TreeSet是SortedSet接口的實現類,TreeSet可以確保集合元素處於排序狀態。TreeSet支持兩種排序方式,自然排序 和定制排序,其中自然排序為默認的排序方式。向TreeSet中加入的應該是同一個類的對象。
TreeSet判斷兩個對象不相等的方式是兩個對象通過equals方法返回false,或者通過CompareTo方法比較沒有返回0。向TreeSet中添加的應該是同一個類的對象,且最好是不可變對象。
1.自然排序
自然排序使用要排序元素的CompareTo(Object obj)方法來比較元素之間大小關系,然后將元素按照升序排列。
Java提供了一個Comparable接口,該接口里定義了一個compareTo(Object obj)方法,該方法返回一個整數值,實現了該接口的對象就可以比較大小。
obj1.compareTo(obj2)方法如果返回0,則說明被比較的兩個對象相等,如果返回一個正數,則表明obj1大於obj2,如果是 負數,則表明obj1小於obj2。
如果我們將兩個對象的equals方法總是返回true,則這兩個對象的compareTo方法返回應該返回0
import java.util.*;
class R implements Comparable
{
int count;
public R(int count)
{
this.count = count;
}
public String toString()
{
return "R(count屬性:" + count + ")";
}
public boolean equals(Object obj)
{
if (obj instanceof R)
{
R r = (R)obj;
if (r.count == this.count)
{
return true;
}
}
return false;
}
public int compareTo(Object obj)
{
R r = (R)obj;
if (this.count > r.count)
{
return 1;
}
else if (this.count == r.count)
{
return 0;
}
else
{
return -1;
}
}
}
public class TestTreeSet2
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet();
ts.add(new R(5));
ts.add(new R(-3));
ts.add(new R(9));
ts.add(new R(-2));
//打印TreeSet集合,集合元素是有序排列的
System.out.println(ts);
//取出第一個元素
R first = (R)ts.first();
//為第一個元素的count屬性賦值
first.count = 20;
//取出最后一個元素
R last = (R)ts.last();
//為最后一個元素的count屬性賦值,與倒數第二個元素count屬性相同
last.count = -2;
//再次輸出count將看到TreeSet里的元素處於無序狀態,且有重復元素
System.out.println(ts);
//刪除屬性被改變的元素,刪除失敗
ts.remove(new R(-2));
System.out.println(ts);
//刪除屬性沒有改變的元素,刪除成功
ts.remove(new R(5));
ts.remove(new R(20));
System.out.println(ts);
}
}
輸出結果:
/*
---------- java運行 ----------
[R(count屬性:-3), R(count屬性:-2), R(count屬性:5), R(count屬性:9)]
[R(count屬性:20), R(count屬性:-2), R(count屬性:5), R(count屬性:-2)] //這里改變之后並沒有重新排序,所以TreeSet中最好放不可改變的對象。
[R(count屬性:20), R(count屬性:-2), R(count屬性:5), R(count屬性:-2)] //刪除-2失敗,因為屬性被改變
[R(count屬性:20), R(count屬性:-2), R(count屬性:-2)] //沒有改變的5可以刪除
輸出完成 (耗時 0 秒) - 正常終止*/
2.定制排序
自然排序是根據集合元素的大小,以升序排列,如果要定制排序,應該使用Comparator接口,實現 int compare(T o1,T o2)方法,該方法用於比較o1和o2的大小:如果該方法返回正整數,則表示o1大於o2;如果方法返回0,則表示o1等於o2,如果該方法返回負整數,則表示o1小於o2。
如果需要定制排序,則需要在創建TreeSet集合時提供一個Comparator對象與該TreeSet集合關聯,由Comparator對象負責幾何元素的排序邏輯:
import java.util.*;
class M
{
int age;
public M(int age)
{
this.age = age;
}
public String toString(){
return "M age:"+age;
}
}
public class TestTreeSet3
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet(new Comparator()
{
public int compare(Object o1, Object o2)
{
/*int age1 = o1 instanceof M ? ((M)o1).age :((N)o1).age;
int age2 = o1 instanceof M ? ((M)o2).age :((N)o2).age;
return age1 - age2;*/
M m1 = (M)o1;
M m2 = (M)o2;
if (m1.age > m2.age)
{
return -1;
}
else if (m1.age == m2.age)
{
return 0;
}
else
{
return 1;
}
}
});
ts.add(new M(5));
ts.add(new M(-3));
ts.add(new M(9));
System.out.println(ts);//[M age:9, M age:5, M age:-3]
}
}
輸出結果·(降序):[M age:9, M age:5, M age:-3]
4.各Set實現類比較:
HashSet和TreeSet是set的兩個典型實現,HashSet的性能比TreeSet好(特別是最常用的添加,查詢元素等操作).只有當需要一個保持排序的Set時,才應該使用TreeSet,否則使用HashSet
LinkedHashSet:對於普通的插入刪除操作,比HashSet慢,遍歷會更快。
另外:Set的三個實現類HashSet,TreeSet和EnemSet都是線程不安全的,如果有多個線程訪問一個Set集合,則必須手動保持同步:
可用Collections的工具類:例如:
SortedSet s = Collections.synchronizedSortedSet(new TreeSet(…));
Set集合終於總結完啦。。
這篇已經夠長啦,List集合在下一篇。。。
轉發請注明:http://www.cnblogs.com/jycboy/p/set.html
