Java集合概述


java中有好多集合:List,ArrayList,Vector,HashSetTreeSet,它們之間的區別,java集合的框架等等總是很模糊,稱有時間總結下。

一、Collection接口和Iterator接口

1.Collection框架:

collection接口主要定義了一些操作集合元素的方法:

boolean

add(E e)

Ensures that this collection contains the specified element (optional operation).如果插入成功,返回true

boolean

addAll(Collection<? extends E> c)

Adds all of the elements in the specified collection to this collection (optional operation).改變返回true

void

clear()

Removes all of the elements from this collection (optional operation).

boolean

contains(Object o)

Returns true if this collection contains the specified element.

boolean

containsAll(Collection<?> c)

Returns true if this collection contains all of the elements in the specified collection.

boolean

equals(Object o)

Compares the specified object with this collection for equality.

int

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM