閱讀50 返回首頁    go 魔獸


集合框架相當重要,大型項目中常用(hash算法用得地方也超多)

什麼要有集合

         麵向對象語言對事物的體現都是以對象的形式體現,所以為了方便對多個對象的操作,就是對對象進行存儲,集合就是存儲對象最常用的一個方式。

數組與集合有什麼不用

       數組的長度是固定的,而集合的長度是可變的。

       數組可以存儲基本數據類型,而集合隻能存儲對象。

集合的特點

集合隻用於存儲對象,集合長度是可變的,集合可以存儲不同類型的對象。

什麼是框架

         框架(framework)是一個類的集,它奠定了創建高級功能的基礎。框架包含很多超類,這些超類擁有非常有用的功能、策略和機製。框架使用者創建的子類可以擴展超類的功能,而不必重新創建這些基本的機製。

集合框架中的類結構圖

集合框架中的接口結構圖

Collection<E>類

           他是所有集合的共性接口類

常用的方法有

    1、添加

boolean add(E e)
          確保此 collection 包含指定的元素(可選操作)。
 boolean addAll(Collection<? extendsE> c)
          將指定 collection 中的所有元素都添加到此 collection 中(可選操作)。

    2、刪除

 boolean remove(Object o)
          從此 collection 中移除指定元素的單個實例,如果存在的話(可選操作)。
 boolean removeAll(Collection<?> c)
          移除此 collection 中那些也包含在指定 collection 中的所有元素(可選操作)。

    3、判斷

boolean contains(Object o)
          如果此 collection 包含指定的元素,則返回 true。
boolean containsAll(Collection<?> c)
          如果此 collection 包含指定 collection 中的所有元素,則返回 true。
boolean isEmpty()
          如果此 collection 不包含元素,則返回 true。

     4、獲取

 int size()
          返回此 collection 中的元素數。
 Iterator<E> iterator()
          返回在此 collection 的元素上進行迭代的迭代器。

    5、其他

Object[] toArray()
          返回包含此 collection 中所有元素的數組。
<T> T[]
toArray(T[] a)
          返回包含此 collection 中所有元素的數組;返回數組的運行時類型與指定數組的運行時類型相同。
boolean retainAll(Collection<?> c)
          僅保留此 collection 中那些也包含在指定 collection 的元素(可選操作)。取2個集合中的元素交集

List與Set的特點

List

    有序:存入和取出的循序一直。

    可以存儲重複對象。

    添加或刪除元素,其後麵的元素後往後移動一位置或向前移動一位置。

    元素都有索引

常用方法:

 void add(int index,E element)
          在列表的指定位置插入指定元素(可選操作)。
 E remove(int index)
          移除列表中指定位置的元素(可選操作)。(返回被刪除的對象)
 E set(int index,E element)
          用指定元素替換列表中指定位置的元素(可選操作)。(返回被修改的對象)
 E get(int index)
          返回列表中指定位置的元素。
 int indexOf(Object o)
          返回此列表中第一次出現的指定元素的索引;如果此列表不包含該元素,則返回 -1。
 int lastIndexOf(Object o)
          返回此列表中最後出現的指定元素的索引;如果列表不包含此元素,則返回 -1。
 List<E> subList(int fromIndex, int toIndex)
          返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之間的部分視圖。(左閉右開)

List實際項目中常用的實現類

    Vector:內部是數組數據結構,是同步的。(都不用了),增刪查詢都很慢。

    ArrayList:內部是數組數據結構,是不同步的。(替代Vector的),查找元素的速度很快,增刪慢。(因為存儲的空間是連續的,所以查起來很快)。

    LinkedList:內部是鏈表數據結構,是不同步的。增刪元素速度很快,查詢速度慢。

集合為什麼大多都不同步?因為效率高。

Set

    可以有序,可以無序,一般情況無序

    不可以存儲重複對象

    元素沒有索引,隻能通過迭代器獲取對象

循環數組

循環數組是一個有界集合,即容量有限。如果程序中要收集的對象數量沒有上限,就最好使用鏈表來實現。

迭代器接口

Iterator(迭代器)接口

集合中的iterator()方法返回一個實現了Iterator接口的實例對象,可以用這個迭代器對象,依次訪問集合中的元素。

Iterator接口中隻有三種方法

如果達到了集合的末尾,next()方法將拋出NoSuchElementException異常。因此,在每次調用next()方法前都要做一下hasNext()的判斷。

例如:

Collection<String> c = ...;

Iterator<String> iter = c.iterator();//獲得c集合的迭代器

while(iter.hasNext()){

      String element = iter.next();

      System.out.print(element);

}

JDK1.5的新特性foe each循環,它可以與任何實現了Iterable(迭代)接口的對象一起工作。其中隻有一個方法Iterator<E> iterator();

next()方法

迭代器可以理解為是位於2個之間的,當調用next()方法的時候,迭代器向前移動一個位置,並返回剛剛越過的那個元素的引用。如圖所示:

刪除元素(remove()方法)和添加元素(add()方法)

Iterator接口的remove()方法將會刪除上次調用next()方法時,返回的那個元素。示例代碼如下:

package paly;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;

public class WorkerTest {
         public static void main(String[] args) {

                LinkedList<String> ll1 = new LinkedList<String>();
                Iterator<String> ll1Iterator = ll1.iterator();//Iterator沒有add方法
                System.out.println(ll1Iterator.hasNext());//返回false
                ListIterator<String> listIterator = (ListIterator<String>) ll1.iterator();
//                ll1Iterator.next();//報錯
                listIterator.add("zhangfan1");//向ll1集合中添加東西
                listIterator.add("zhangfan2");//向ll1集合中添加東西
                listIterator.add("zhangfan3");//向ll1集合中添加東西
                listIterator.add("zhangfan4");//向ll1集合中添加東西
                listIterator.add("zhangfan5");//向ll1集合中添加東西
                myIterator(ll1);
//                System.out.println(listIterator.hasNext());//迭代器裏麵沒有東西
//                listIterator.remove();//這裏報錯
//                ll1Iterator.remove();//這裏報錯,估計要重新再次獲得迭代器吧
//                ll1Iterator.next();
                listIterator = ll1.listIterator();//重新獲得迭代器
                System.out.println("將迭代器想右移動一位置:"+listIterator.next());//------位置一
                listIterator.remove();//結果zhangfan1被刪除了------位置二
//                listIterator.remove();//這裏報錯,因為迭代器,在位置二的時候,已經把它越過的前一元素給刪除了,現在這裏沒有元素,所以不能刪除
//              現在刪除zhangfan3
//              由於在位置一的時候迭代器向後越過了一位置,返回的是zhangfan1,而zhangfan1在位置二的時候被刪除,現在要刪除zhangfan3就要在向後越過2元素
                myIterator(ll1);
                listIterator.next();
                listIterator.next();
                listIterator.remove();//刪除zhangfan3
                System.out.println("刪除zhangfan3以後");
                myIterator(ll1);
         }
         
         public static void myIterator(Iterable a){//Collection
        	 Iterator<String> temp = a.iterator();
        	 while (temp.hasNext()) {
				System.out.println(temp.next());
			}
         }
 }

運行結果:

false
zhangfan1
zhangfan2
zhangfan3
zhangfan4
zhangfan5
將迭代器想右移動一位置:zhangfan1
zhangfan2
zhangfan3
zhangfan4
zhangfan5
刪除zhangfan3以後
zhangfan2
zhangfan4
zhangfan5

Collections類

static
<T> int
binarySearch(List<? extendsComparable<? super T>> list, T key)
          使用二分搜索法搜索指定列表,以獲得指定對象。

1、返回int,如果有要找的key就返回,key所在的位置。

2、返回int,如果沒有要找的key就返回負數,並帶添加次key值的插入點,並且插入進去後,數組還是拍好序列的,裏麵是-min-1,所以用得到的負數+1,取正就是插入點的索引

static
<T> int
binarySearch(List<? extends T> list, T key,Comparator<? super T> c)
          使用二分搜索法搜索指定列表,以獲得指定對象。

1、根據自定義比較器,進行比較,Comparator是一個接口,其中的比較方法要程序員自己實現。

Arrays類

static
<T> List<T>
asList(T... a)
          返回一個受指定數組支持的固定大小的列表。

LinkedList<E>類

鏈表(相關類:List、LinkedList<E>、Iterator<E>、ListIterator<E>、Iterable<T>)

       在數組和數組列表中,有很大的一個缺陷,就是每次添加非隊列末尾的一個元素時,其後麵的元素都要向後移一位置,或每次刪除非隊列末尾的一個元素時,其後麵的元素都要向前移動一個位置。這就是其添加和刪除的效率不高。而鏈表很好的解決了這一問題。

       在Java程序設計語言中,所有鏈表實際上都是雙向鏈接的。即每個結點還存放著指向前驅結點的引用。如下圖所示:

刪除一個元素:

鏈表和泛型集合的重要區別是:鏈表是一個有序集合。

LinkedList<E>的add()方法是將元素添加到集合的末尾,但常常要添加到其他元素的中間,用Iterator<E>接口的子接口ListIterator<E>實現添加的功能,還可以向前查詢元素

示例代碼:

package paly;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;

public class WorkerTest {
         public static void main(String[] args) {

                LinkedList<String> ll1 = new LinkedList<String>();
                Iterator<String> ll1Iterator = ll1.iterator();//Iterator沒有add方法
                System.out.println(ll1Iterator.hasNext());//返回false
                ListIterator<String> listIterator = (ListIterator<String>) ll1.iterator();
//                ll1Iterator.next();//報錯
                listIterator.add("zhangfan1");//向ll1集合中添加東西
                listIterator.add("zhangfan2");//向ll1集合中添加東西
                listIterator.add("zhangfan3");//向ll1集合中添加東西
                listIterator.add("zhangfan4");//向ll1集合中添加東西
                listIterator.add("zhangfan5");//向ll1集合中添加東西
    
                ll1.add("zhangfan6");//調用的是LinkedList的add方法,那它還在zhangfan5的後麵
                System.out.println("----------------添加zhangfan6");
                myIterator(ll1);
//              現在在zhangfan4和zhangfan5之間添加3個元素看看效果
                listIterator =ll1.listIterator();//重新獲得迭代器
                System.out.println("-------------迭代器剛剛越過的元素:"+listIterator.next());//不知道迭代器現在的位置在哪,打印出來看看
                listIterator.next();//越過zhangfan2
                listIterator.next();//越過zhangfan3
                listIterator.next();//越過zhangfan4,現在迭代器在zhangfan4和zhangfan5之間
                listIterator.add("zhangfan7");
                listIterator.add("zhangfan8");
                listIterator.add("zhangfan9");
                myIterator(ll1);
                System.out.println("--------------向前查詢元素:"+listIterator.previous()+"下一個index:"+listIterator.nextIndex());
                System.out.println("--------------向前查詢元素:"+listIterator.previous()+"前一個index:"+listIterator.previousIndex());
                System.out.println("--------------向前查詢元素:"+listIterator.previous()+"前一個index:"+listIterator.previousIndex());
                System.out.println("--------------向前查詢元素:"+listIterator.previous()+"前一個index:"+listIterator.previousIndex());
         }
         
         public static void myIterator(Iterable a){//Collection
        	 Iterator<String> temp = a.iterator();
        	 while (temp.hasNext()) {
				System.out.println(temp.next());
			}
         }
 }

LinkedList也提供了get(int i)方法來查詢元素,但是效率極其低下。

麵試題:10、 有100個人圍成一個圈,從1開始報數,報到14的這個人就要退出。然後其他人重新開始,從1報數,到14退出。問:最後剩下的是100人中的第幾個人?

package paly;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

/**
 * 10、 有100個人圍成一個圈,從1開始報數,報到14的這個人就要退出。然後其他人重新開始,
 * 從1報數,到14退出。問:最後剩下的是100人中的第幾個人?
 *
 * @author Terry
 * @date 2014-6-9
 *
 */
public class Test10 {
	static int howPoeple = 5674;
	int indexRecord = 0;//索引記錄
	static final List<People> circlePeople = new ArrayList<People>();//圓圈
	static LinkedList<People> linkedList = new LinkedList<People>();
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//看了運行結果,感覺不對,先做其他的,然後回來用麵向對象的方式對比看看
		begin(346);	
		counOffByLinkedList(howPoeple,346);
		System.out.println("最後剩下"+howPoeple+"人中的第"+linkedList.getFirst().getNumber()+"人");
	}
	
	
	
	
	/**
	 * 測試重新獲得迭代器,迭代器位置會變成第一個不,結果會還原
	 */
	public static void test(){		
		for (int i = 0; i < 5; i++) {
			People people = new People();
			people.setNumber(i);
			linkedList.add(people);
		}
		ListIterator<People> li = linkedList.listIterator();
		System.out.println(li.hasNext());
		for (int i = 0; i < 5; i++) {
			System.out.println(li.next().getNumber());
		}
		
		li = linkedList.listIterator();
		System.out.println("------"+li.next().getNumber());
	}
	
	/**
	 * 用LinkedList來實現
	 * @param size:有多少人
	 * @param index:第幾個人開始報數
	 */
	public static void counOffByLinkedList(int size,int index){	
		for (int i = 1; i < size+1;i++) {
			People people = new People();
			people.setNumber(i);
			linkedList.add(people);
		}
		beginCountin(linkedList,index);	
	}
	
	/**
	 * 開始報數方法
	 * @param index,第幾個人開始報數
	 */
	public static void beginCountin(List list,int index){
		ListIterator<People> listIterator = list.listIterator(index);
		beginCountin(listIterator);
	}
	
	public static void beginCountin(ListIterator listIterator ){
		/**
		 * 報數1-14
		 */
		for (int i = 0; i < 14; i++) {
			if(listIterator.hasNext()){
				listIterator.next();//報數
			}else{
				listIterator = linkedList.listIterator();//重新迭代
				if(listIterator.hasNext()){
					listIterator.next();//報數
				}
			}
		}
		if(linkedList.size()>2){
			listIterator.remove();
			beginCountin(listIterator);
		}
		if(linkedList.size()>1){
			listIterator.remove();
		}
	}
	
	
	
	
	
	/**
	 * 人們開始報數,每報到14,報到14的那個人退出,其他人繼續報數
	 * @param index 取值 index>=0 index<howPoeple,位置index的人第一個報數
	 */
	public static void countOff(int index){
		List<People> people = Test10.circlePeople;
		if(people.size()==3){//這裏是給debug用的,用來快速到達錯誤的地方
			System.out.println();
		}
		for (int i = 0; i < 14; i++) {
			if(index==people.size()){//index = poeples.size()-1,表示數組中的最後一個人了,index==poeples.size()
//				表示應該是最後一個人的下一個人,也就是返回到第一個人了
				index = 0;//又從第一個人開始
			}
//			People temp = poeples.get(index);//這個人報數,喊完過後,後一個位置的人報數。輔助思考用的
			if(i == 13){//代表著要退出一個人了,從1開始報數報,這是第14次報數,前麵==13因為索引是從0開始的
				if(people.size()>2){//圈裏的人數有3人以上
					/**
					 * 代表著數組中的第一個人要退出,然後他後麵的人和最後一個人牽手,
					 * 最後一個人的右邊是第二個人,第二個人的左邊是最後一個人
					 */
					if(index == 0){
						if(people.size() == 1){//如果圈裏麵隻剩下一個人就不退出了
							break;
						}
						People me = people.get(index);//要退出的人
						People lastPeople = people.get(people.size()-1);
						People afterMe = people.get(index + 1);
						lastPeople.setRightPeople(afterMe);
						afterMe.setLeftPeople(lastPeople);
						people.remove(me);
						System.out.println(people.size()+"::index="+index);
						countOff(index);//這裏本想index++;的,但是ArrayList元素刪除的時候,被刪元素的後麵元素都會向前移一個位置	
					}
					/**
					 * 代表著數組中的最後一個人要退出,然後他前麵的人和第一個人牽手,
					 * 第一個人的左邊是他前麵的人,他前麵的人的右邊是第一個人
					 */
					if(index == people.size()-1){
						if(people.size() == 1){//如果圈裏麵隻剩下一個人就不退出了
							break;
						}
						People me = people.get(index);//要退出的人
						People firstPeople = people.get(0);
						People beforeMe = people.get(people.size()-1-1);
						firstPeople.setLeftPeople(beforeMe);
						beforeMe.setRightPeople(firstPeople);
						people.remove(me);
						index = 0;//最後一個元素都移除了,他後麵沒有元素了,所以要從0開始
						System.out.println(people.size()+"::index="+index);
						countOff(index);
					}
					//做到這裏發現,單獨people對其中的左右people交換的時候,可以封裝成一個方法,那代碼量將會少很多
					if(people.size() == 1){//如果圈裏麵隻剩下一個人就不退出了
						break;
					}
					People me = people.get(index);//要退出的人
					People afterMe = people.get(index + 1);
					People beforeMe = people.get(index - 1);
					afterMe.setLeftPeople(beforeMe);
					beforeMe.setRightPeople(afterMe);
					people.remove(me);
					System.out.println(people.size()+"::index="+index);
					countOff(index);
				}else{
					people.remove(index);
				}
			}
			index ++;//每報一次數,數組索引往後移一位置
		}
	}
	
	/**
	 * 第一個人和其他2人牽手的方式
	 * 第一個人和其他2人牽手,他的左邊是最後一個人,他的右邊是第二個人
	 */
	public static void fasePeople(int i){//為了方便,這裏用static好了,多花點內存,就多花點了,不管那麼多了
		List<People> temp = Test10.circlePeople;
//		if(i == 0){
			People me = temp.get(i);
			People leftPeople = temp.get(temp.size()-1);
			People rightPeople = temp.get(i+1);
			me.setLeftPeople(leftPeople);
			me.setRightPeople(rightPeople);
//		}
	}
	/**
	 * 最後一個人和其他2人牽手的方式
	 * 最後一個人和其他2人牽手,他的左邊是倒數第二的人,他的右邊是第一個人
	 */
	public static void lastPeople(int i){
		List<People> temp = Test10.circlePeople;
//		if(i == temp.size()-1){
			People me = temp.get(i);
			People leftPeople = temp.get(i-1);
			People rightPeople = temp.get(0);
			me.setLeftPeople(leftPeople);
			me.setRightPeople(rightPeople);
//		}
	}
	/**
	 * 第二個人和第二個以後的人和其他2個人牽手,他的左邊是他前麵的那個人,他的右邊是他後麵的那個人
	 */
	public static void secondAndOtherPeople(int i){
		List<People> temp = Test10.circlePeople;
		People me = temp.get(i);
		People leftPeople = temp.get(i-1);
		People rightPeople = temp.get(i+1);
		me.setLeftPeople(leftPeople);
		me.setRightPeople(rightPeople);
	}
	
	/**
	 * 開始
	 * @param index,0-howPoeple之間
	 */
	public static void begin(int index){
		Test10 test10 = new Test10();
		// TODO Auto-generated method stub
		//howPoeple個人站在一起//這裏可以用享元模式
		for (int i = 1; i < test10.howPoeple+1; i++) {
			People people = new People();
			people.setNumber(i);
			test10.circlePeople.add(people);
		}
		
		//howPoeple個人手拉手圍成一個圓圈
		for (int i = 0; i < test10.howPoeple; i++) {			
//			 第一個人和其他2人牽手,他的左邊是最後一個人,他的右邊是第二個人			 
			if(i == 0){
				fasePeople(i);
				continue;
			}
//			 最後一個人和其他2人牽手,他的左邊是倒數第二的人,他的右邊是第一個人
			if(i == circlePeople.size()-1){
				lastPeople(i);
				continue;
			}
//			第二個人和第二個以後的人和其他2個人牽手,他的左邊是他前麵的那個人,他的右邊是他後麵的那個人
			    secondAndOtherPeople(i);
		}	
		
		countOff(index);
		
		System.out.println("最後剩下"+howPoeple+"人中的第"+Test10.circlePeople.get(0).getNumber()+"人");
	}
}

class People{
	private int number;//自己的編號
	private People leftPeople;//左邊的人
	private People rightPeople;//右邊的人
	
	
	public int getNumber() {
		return number;
	}
	public void setNumber(int number) {
		this.number = number;
	}
	public People getLeftPeople() {
		return leftPeople;
	}
	public void setLeftPeople(People leftPeople) {
		this.leftPeople = leftPeople;
	}
	public People getRightPeople() {
		return rightPeople;
	}
	public void setRightPeople(People rightPeople) {
		this.rightPeople = rightPeople;
	}
	
	
}

HashTable類

散列表hash table,可以快速地查找所需要的對象。散列表為每個對象計算一個整數,稱為散列碼(hash code).

hashcode的作用:
首先,想要明白hashCode的作用,你必須要先知道Java中的集合。  
總的來說,Java中的集合(Collection)有兩類,一類是List,再有一類是Set。
前者集合內的元素是有序的,元素可以重複;後者元素無序,但元素不可重複。
那麼這裏就有一個比較嚴重的問題了:要想保證元素不重複,可兩個元素是否重複應該依據什麼來判斷呢?
這就是Object.equals方法了。但是,如果每增加一個元素就檢查一次,那麼當元素很多時,後添加到集合中的元素比較的次數就非常多了。
也就是說,如果集合中現在已經有1000個元素,那麼第1001個元素加入集合時,它就要調用1000次equals方法。這顯然會大大降低效率。   
於是,Java采用了哈希表的原理。哈希(Hash)實際上是個人名,由於他提出一哈希算法的概念,所以就以他的名字命名了。
哈希算法也稱為散列算法,是將數據依特定算法直接指定到一個地址上。
初學者可以這樣理解,hashCode方法實際上返回的就是對象存儲的物理地址(實際可能並不是)。  
這樣一來,當集合要添加新的元素時,先調用這個元素的hashCode方法,就一下子能定位到它應該放置的物理位置上。
如果這個位置上沒有元素,它就可以直接存儲在這個位置上,不用再進行任何比較了;如果這個位置上已經有元素了,
就調用它的equals方法與新元素進行比較,相同的話就不存了,不相同就散列其它的地址。
所以這裏存在一個衝突解決的問題。這樣一來實際調用equals方法的次數就大大降低了,幾乎隻需要一兩次。  
所以,Java對於eqauls方法和hashCode方法是這樣規定的:
1、如果兩個對象相同,那麼它們的hashCode值一定要相同;

2、如果兩個對象的hashCode相同,它們並不一定相同,上麵說的對象相同指的是用eqauls方法比較。  
當然可以不按要求去做了,但會發現,相同的對象可以出現在Set集合中。同時,增加新元素的效率會大大下降。

示例代碼:

 String a = new String("BBC");
        	 String b = "bbc";
        	 String c = new String();
        	 String d = "bbc";
             System.out.println(a.hashCode());
             System.out.println(b.hashCode());
             System.out.println(c.hashCode());
             System.out.println(d.hashCode());

運行輸出:

65539
97315
0
97315
在Java中,散列表用鏈表數組實現。每個列表被稱為桶。想要查找表中對象的位置,就要先計算它的散列碼,然後與桶的總數取餘,所得到的結果就是保存這個元素的桶的索引。例如:

如果某個對象的散列碼為76268,並且有128個桶,對象應該保存在第108號桶中(76268%128=108)。或許會很幸運,在這個桶中沒有其他元素,此時將元素直接插入到桶中就可以了。當然,有時候會遇到桶被占滿的情況,這也是不可能避免的。這種現象被稱為散列衝突。這時,需要用新對象與捅中的所有對象進行比較,查看這個對象是否已經存在。

TreeSet類

  TreeSet類是一個有序不重複集合,它每次添加元素的時候都會進行比較,然後再按順序添加,所以添加的速度很慢。它的底層數據結構是二叉樹。

它有2中排序的方式:一種是,添加的元素自身可以排序,實現了Comparable

                                   另一種是,你給TreeSet定義一個比較器(Comparator),TreeSet根據Comparatro的

 int compare(T o1, T o2)
          比較用來排序的兩個參數。

來進行比較。當兩種排序都存在是優先用給定的比較器進行比較。

示例代碼:

 SortedSet<String> sorter = new TreeSet<String>();
        	 sorter.add("dbc");
        	 sorter.add("BBC");
        	 sorter.add("bbc");
        	 sorter.add("cbc");
        	 sorter.add("abc");
        	 for (String string : sorter) {
				System.out.println(string);
			}

運行結果:

BBC
abc
bbc
cbc
dbc


TreeSet(Comparator<? super E> comparator)


 boolean addAll(Collection<? extendsE> c)
          將指定 collection 中的所有元素添加到此 set 中。


          構造一個新的空 TreeSet,它根據指定比較器進行排序。

存儲自定義對象,並按自定義對象的某個屬性,進行排序

<pre  name="code">package paly;

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

public class TreeSetTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Comparator<People> comparator = new Comparator<People>() {
			@Override
			public int compare(People o1, People o2) {
				// TODO Auto-generated method stub
//				return o1.name.compareTo(o2.name);//指定用名字比較
//				System.out.println(o1.getName()+"---"+o2.getName());//由此可以看出,o1是後添加進來的對象
				if(!(o1 instanceof People)){
					throw new RuntimeException("不是People對象");
				}
				return o2.age - o1.age;//指定用名字比較
			}
		};
		TreeSet peoples = new TreeSet<People>(comparator);
		peoples.add(new People("張帆",27));
		peoples.add(new People("小帥",12));//這裏報錯,我想應該是要指定Comparator比較器吧
		peoples.add(new People("敬先林",20));
		peoples.add(new People("董華俊",30));
//		peoples.add(new Object());
		Iterator<People> iterator = peoples.iterator();
		while(iterator.hasNext()){
			People temp = iterator.next();
			System.out.println(temp.name+"---"+temp.age);
		}
	}
	
	static class People{//靜態方法中要用靜態類
		public People(String name,int age){
			this.name = name;
			this.age = age;
		}
		private String name ;
		private int age;
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public int getAge() {
			return age;
		}
		public void setAge(int age) {
			this.age = age;
		}
		
		
	}
	
}


另一種寫法

package paly;

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

public class TreeSetTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub		
		TreeSet peoples = new TreeSet<People>();
		peoples.add(new People("張帆",27));
		peoples.add(new People("小帥",12));//這裏報錯,我想應該是要指定Comparator比較器吧
		peoples.add(new People("敬先林",20));
		peoples.add(new People("董華俊1",30));
		peoples.add(new People("董華俊2",30));
//		peoples.add(new Object());
		Iterator it = peoples.iterator();
		while(it.hasNext()){
			People temp = (People) it.next();
			
			System.out.println(temp.name+"--"+temp.age);
		}
	}
	
	static class People implements Comparable{//靜態方法中要用靜態類
		public People(String name,int age){
			this.name = name;
			this.age = age;
		}
		private String name ;
		private int age;
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public int getAge() {
			return age;
		}
		public void setAge(int age) {
			this.age = age;
		}
		@Override
		public int compareTo(Object o) {
			// TODO Auto-generated method stub
//			return 1;//if這裏返回1的話,更具二叉樹原理就是,怎麼存的怎麼取;return 0,隻有一個元素
			if(!(o instanceof People)){
				System.out.println(1);
				throw new RuntimeException("對象不是People類型的");
			}
			People people = (People)o;
			System.out.println(this.name+"---compareTo:"+people.name);
			if(this.age>people.age)
				return 1;
			if(this.age==people.age){//如果年齡相同,就在判斷名字是否相同,如果屬性有上百個呢?我會比較hashcode
				System.out.println(this.hashCode()+"--"+people.hashCode());
//				return 0;//如果這return 0,的話就會出現new People("董華俊2",30),加不進集合,因為係統會認為他們是同一對象
				return this.name.compareTo(people.name);
			}
				
			return -1;
		}
		
		
	}
	
}


集合數組之間的轉換

集合轉數組

public static void b() {
		// TODO Auto-generated method stub
		List<String> b = new ArrayList<String>();
		b.add("haha1");
		b.add("haha2");
		b.add("haha3");
		Object [] a =  b.toArray();
		for (int i = 0; i < a.length; i++) {
			System.out.println(a[i]);
		}
		
	}

數組轉集合

// TODO Auto-generated method stub
		String [] a = new String[]{"a","b","c","d"};
		List<String> b = Arrays.asList(a);
		Iterator<String> c = b.iterator();
		while(c.hasNext()){
			System.out.println(c.next());
		}







最後更新:2017-04-03 07:57:00

  上一篇:go what is the Structural mechanics(什麼是結構力學?)
  下一篇:go 什麼是竹子精神?