黑馬程序員_java_集合框架_Collection_List_Set_泛型

  ------- android培訓java培訓、期待與您交流! ----------




一、集合框架


爲什麼會出現這麼多的容器呢?
因爲每一個容器對數據的存儲方式都有不同。
這個存儲方式稱之爲:數據結構


Collection  也可以稱之爲單列集合
       |--List:元素是有序的。輸入的元素可以重複,因爲該結合體繫有索引


          |--ArrayList:底層的數據結構使用的是數組結構。特點:查詢速度快。但是增刪稍慢,線程不同步


          |--LinkedList:底層的數據結構是鏈表數據結構。特點。增刪速度快。但是查詢速度慢,


 |--Vector:底層的數據結構是數組結構。   線程同步。但是被ArrayList替代了。
枚舉是Vector特有的取出方式。
發現枚舉和迭代器很像
其實枚舉和迭代器是一樣的。
因爲枚舉的名稱以及方法的名稱都過長
所以被迭代器去取代了
而枚舉就鬱鬱而終
示例代碼
	import java.util.Vector;
	import java.util.Enumeration;


	class VectorDemo 
	{
		public static void main(String[] args) 
		{
			Vector v = new Vector();
			v.add("java01");
			v.add("java02");
			v.add("java03");


			//使用枚舉遍歷集合中的元素
			Enumeration e = v.elements();
			for( ; e.hasMoreElements(); )
			{
				System.out.println(e.nextElement());
			}
		}
	}






       |--Set:該集合元素是無序的。輸入的元素不可以重複。因爲該體系中沒有索引


 |--HashSet:底層數據結構是哈希表  線程是非同步的
HsshSet是如何保證元素唯一性的呢?
是通過元素的兩個方法,hashCode和equals來完成。
如果元素的HashCode的值相同,,纔會判斷equals是否爲true。
如果原數的HashCode的值不同,纔會調用equals


TreeSet的第二種排序方式。
當元素自身不具備比較性時,或者具備的比較性不是所需要的,這時就需要讓集合自身具備比較性。
在集合初始化時,就有了比較性。    


當兩種排序都存在時,一比較器爲主。


注意,對於判斷元素是否存在,以及刪除等操作,依賴的方法元素的hashCode和equals方法


	import java.util.HashSet;
	import java.util.Iterator;


	class HashSetDemo 
	{
		public static void main(String[] args) 
		{
			//創建一個容器
			HashSet hs = new HashSet();
			hs.add("java01");
			hs.add("java02");
			hs.add("java02");
			hs.add("java02");
	
			//創建一個迭代器
			Iterator it = hs.iterator();
			for( ; it.hasNext(); )
			{
				System.out.println(it.next()); //結果爲java02 java01
			}
		}
	}








 |--TreeSet:可以對set集合中的元素進行排序。排序規則是參照英文字母的自然排序


底層結構是二叉樹,保證元素唯一性的依據;compareTo方法return 0代表元素相同

TreeSet排序的第一種方式:讓元素自身具備比較性。
元素需要實現Comparable接口,覆蓋compareTo方法
這種方式也稱爲元素的自然排序,或者叫做默認排序


示例:
需求:往TreeSet集合中存儲自定義對象學生。
想按照學的年齡就行排序。


記住了,排序時,當主要條件相同時,一定判斷一下次要條件


	import java.util.TreeSet;
	import java.lang.Comparable;
	import java.util.Iterator;


	class TreeSetTest
	{
		public static void main(String[] args) 
		{	
			//創建一個容器
			TreeSet ts = new TreeSet();
			ts.add(new Students("張三", 23));
			ts.add(new Students("李四", 32));
			s.add(new Students("王五", 23));
		
			//創建一個迭代器
			Iterator it = ts.iterator(); //只要容器中有元素。it.hasNext()結果永遠爲真。程序就能運行下去。一旦爲false。就停止
			for( ; it.hasNext(); )
			{
				Students s = (Students)it.next(); //因爲it.next()是父類印象指向子類對象。所以在這裏要做強轉
				System.out.println(s.getName() + "," + s.getAge());
			}
		}
	}


	//寫一個學生類
	class Students implements Comparable //實現Comparable接口。對學生對象進行自定義排序
	{
		private String name;
		private int age;
		Students(String name, int age)
		{
			this.name = name;
			this.age = age;
		}


		//重寫Comparable接口的方法
		public int compareTo(Object obj)
		{
			if(!(obj instanceof Students)) //判斷一下是否是學生對象
				throw new RuntimeException("對象不是學生對象");
			Students s = (Students)obj;
			if(this.age > s.age) //假如傳進來的對象年齡小於原來的對象年齡。就返回1
				return 1;
			if(this.age == s.age)
			{
				return this.name.compareTo(s.name); //如果年齡一樣的話。就比較名字。讓名字按照英文字母的順序排列
			}
			return -1;
		}


		public void setName(String name)
		{
			this.name = name;
		}


		public String getName()
		{
			return name;
		}


		public void setAge(int age)
		{
			this.age = age;
		}


		public int getAge()
		{
			return age;
		}
	}





Set集合的功能和Collection是一致的





二、Collection的基本應用。和迭代器的基本使用


import java.util.ArrayList;
import java.util.Iterator;
/*
1,add方法的參數是Object.以便於接收任意類型對象。
2集合中存儲的都是對象的引用(也就是地址)


常用函數
add(); 添加元素
size(); 求集合的長度
contains(String); 判斷String字符是否存在於集合中
isEmpty(); 此函數判斷集合是否爲空
remove(String) 刪除數組中的Sring元素
clear(); 清空集合


retainAll()  去交集
remove() 刪除有交集的元素


什麼是迭代器?
其實就是集合的取出元素的方式。
把取出方式定義在集合的內部,
這樣取出方式就可以直接訪問集合內容的元素。


那麼取出方式就被定義成了內部類。


而每一個容器的數據結構不同。
所以取出的動作細節也不一樣,但是都有共性內容。
判讀和取出。那麼可以可以將共性抽取。


所以這些內部類都符合一個規則。該規則就是Iterator.
如何取出集合的取出對象呢?
通過一個對外提供的方法iterator();
*/


class CollectionDemo 
{
	public static void main(String[] args) 
	{
		//mothed_1();
		//mothed_2();
		dieDai();
	}


	//結合容器Collection的一個基本應用
	public static void mothed_1()
	{
		//創建一個集合容器,使用Collection接口的子類。ArrayList
		ArrayList  a1 = new ArrayList();
		
		//添加元素
		a1.add("java01");
		a1.add("java02");
		a1.add("java03");
		a1.add("java04");


		//獲取個數。求集合的長度
		p("長度是:" + a1.size());


		//打印集合
		p("原集合:" + a1);


		//判斷java03元素是否存在    運用contains函數
		p("java03是否存在於集合中:" + a1.contains("java03"));


		//判斷集合是否爲空  運用isEmpty()函數
		p("判斷集合是否爲空:" + a1.isEmpty());




		//刪除集合
		a1.remove("java03"); //調用remove函數刪除集合中的元素
		p("刪除單個元素後的集合:" + a1);


		a1.clear(); //調用clear清空集合
		p("清空後的集合:" + a1);
	}
	
	//集合中的交集小例子
	public static void mothed_2()
	{
		//創建一個集合容器,使用Collection接口的子類。ArrayList
		ArrayList  a1 = new ArrayList();
		
		//添加元素
		a1.add("java01");
		a1.add("java02");
		a1.add("java03");
		a1.add("java04");
		
		ArrayList a2 = new ArrayList();
		//添加元素
		a2.add("java01");
		a2.add("java02");
		a2.add("java05");
		a2.add("java06");
		//a1.retainAll(a2); //判斷兩個容器是否有交集的地方,有的話。把交集的內容打印,.可以剪短的稱之爲取交集
		//p(a1);
		a1.removeAll(a2); //幹掉相同的元素
		p(a1); 
	}


	//簡單應用迭代器
	public static void dieDai()
	{
		ArrayList s = new ArrayList();
		s.add("java01");
		s.add("java02");
		s.add("java03");
		s.add("java04");
		/*   此爲while循環
		//獲取迭代器 使用迭代器取出集合中的元素
		Iterator it = s.iterator();
		while(it.hasNext()) //判斷集合中是否有內容。有就往下執行
		{
			p(it.next()); //打印輸出集合中的內容
		}
		*/
		//使用for循環使用迭代器
		for(Iterator it = s.iterator(); it.hasNext(); )
		{
			p(it.next());
		}


	}
	
	public static void p(Object obj)
	{
		System.out.println(obj);
	}


}







二、List接口的使用


import java.util.ArrayList;
import java.util.ListIterator;




List
特有方法、凡是可以操作角標的方法都是該體系特有的方法
1、增加
add(index,element); 在角標爲index的位置上插入element元素
addAll(index,Collection); 在角標位置爲index的位置上插入一組元素
2、刪除
remove(index); 刪除角標位置爲index上的元素
3、修改
set(index,element); 修改角標位置爲index上的元素
4、查找
get(index); 查找角標位置爲index上的元素
subList(from,to); 查找角標位置從from到to但並不包含to的一組元素
listIterator(); 


List集合特有的迭代器,ListIterator是Iterator的子接口。


在迭代時,不可以通過集合對象的方法操作集合中的元素。
因爲會發生ConcurrentModificationException(併發修改異常)


所以,在迭代器時,只能用迭代器的方法操作元素,可是Iterator方法是有限的。
只能對元素進行判斷,取出,刪除的操作,
如果想要其他操作如添加。修改等,就需要使用其子接口,ListIterator;


該接口只能通過list集合的listIterator方法獲取。




class ListDemo 
{
	public static void main(String[] args) 
	{
		//list();
		list_1();
	}
	
	//List的簡答應用
	public static void list()
	{
		//創建一個集合容器,使用Collection的子類ArrayList
		ArrayList s = new ArrayList();
		//添加元素
		s.add("java01");
		s.add("java02");
		s.add("java03");
		p("添加前:" + s);
		//增加元素
		s.add(2,"java05"); //在角標位爲2的位置插入元素
		p("添加後:" + s);
		
		s.remove(3); //刪除角標位爲3的元素
		p("刪除後:" + s);


		s.set(2, "java08"); //把角標位爲2的元素修改成java08
		p("修改後:" + s);


		p("查找的單個元素是:" + s.get(2)); //查找角標位爲2的數組上的元素
 
		p("查找到的多個元素:" + s.subList(0,3)); //以爲此方法查找包含頭,不包含尾。所以要查找到到所有元素。必須要比元素個數大1
		


	}


	//ListIterator的簡單應用
	public static void list_1()
	{
		ArrayList s = new ArrayList();
		s.add("java01");
		s.add("java02");
		s.add("java03");
		ListIterator li = s.listIterator();
		//使用List特有的迭代器ListIterator
		for(; li.hasNext(); )
		{
			Object obj = li.next(); //子類對象指向父類引用
			if(obj.equals("java03"))
			{
				li.set("java---3"); //對迭代器中的元素進行修改
				li.add("java-----3"); //對迭代器中的元素進行添加
			}
		}
		p("從頭往後遍歷:" + s);


		for(; li.hasPrevious(); )
		{
			p(li.previous()); //從後往前遍歷
		}
		
	}


	public static void p(Object obj)
	{
		System.out.println(obj);
	}
}







三、類LinkedList的簡單應用


import java.util.LinkedList;


/*
LinkedLIST:特有方法
addFirst(); 每次都把元素添加在第一位
addLast(); 每一次都把元素添加到最後一位


//獲取元素,但是並不刪除元素。如果集合中沒有元素,會出現NoSuchEmelemtException異常
getFirst(); 獲取最前面的一位元素
getLast(); 獲取最後面的一位元素


//獲取元素,但是元素被刪除。如果集合中沒有元素,會出現NoSuchEmelemtException異常
removeFirst(); 刪除最前面的一位元素
removeLast(); 刪除最後面的一位元素


在jdk1.6中出現了替代的方法。


offerFirst(); 每次都把元素添加在第一位
offerLast(); 每一次都把元素添加到最後一位


//獲取元素,但是並不刪除元素。如果集合中沒有元素,會出現null;
peekFirst(); 獲取最前面的一位元素
peekLast(); 獲取最後面的一位元素


//獲取元素,但是元素被刪除。如果集合中沒有元素,會出現null;
pollFirst(); 刪除最前面的一位元素
pollLast(); 刪除最後面的一位元素

*/


class LinkedListDemo 
{
	public static void main(String[] args) 
	{
		//mothed();
		mothed_1();
	}


	//寫一個1.6以後出現的新特性的應用函數
	public static void mothed_1()
	{
		//創建一個集合
		LinkedList l = new LinkedList();


		l.offerFirst("java02"); //addFirst();每次輸入進去的元素都放在第一位。把原來第一位上的元素擠到後面去
		l.offerFirst("java01"); //所以結果爲:[java01, java02]
		p(l);


		l.offerLast("java03"); //addLast();每次輸入的元素都放在最後一位。並把原來排在最後一位的元素往前擠
		l.offerLast("java04"); //所以結果爲:[java01, java02, java03, java04]
		p(l);


		//獲取第一個元素和最後一個元素
		p("第一個元素是:" + l.peekFirst());
		p("最後一個元素是:" + l.peekLast());


		//刪除第一個元素
		l.pollFirst();
		p(l);


		//刪除最後一個元素
		l.pollLast();
		p(l);
	}


	//寫一個LinkedList類的應用函數
	public static void mothed()
	{
		//創建一個集合
		LinkedList l = new LinkedList();


		l.addFirst("java01"); //addFirst();每次輸入進去的元素都放在第一位。把原來第一位上的元素擠到後面去
		l.addFirst("java02"); //所以輸出結果是:[java04, java03, java02, java01]
		l.addFirst("java03");
		l.addFirst("java04");
		p(l);


		l.addLast("java05"); //addLast();每次輸入的元素都放在最後一位。並把原來排在最後一位的元素往前擠
		l.addLast("java06"); //所以輸出的結果是:[java04, java03, java02, java01, java05, java06, java07, java08]
		l.addLast("java07");
		l.addLast("java08");
		p(l);


		p("最前面的元素是:" + l.getFirst());
		p("最後面的元素是:" + l.getLast());
		
		l.removeFirst();
		p(l); //刪除最前面的元素。結果爲:[java03, java02, java01, java05, java06, java07, java08]
		l.removeLast();
		p(l); //刪除最後面的元素。結果爲:[java03, java02, java01, java05, java06, java07]
	}


	public static void p(Object obj)
	{
		System.out.println(obj);
	}


}







四、堆棧與隊列


/*
使用LinkedList模擬出一個堆棧或者隊列的數據結構
堆棧:先進後出
隊列:先進先出
*/


import java.util.LinkedList;


//寫一個對列
class DuiLie
{
	private LinkedList ll;
	DuiLie()
	{
		ll = new LinkedList();		
	}
	
	//輸入元素
	public void myAdd(Object obj)
	{
		ll.addFirst(obj); //把每次傳進來的元素都放在第一位
	}


	//獲取元素
	public Object myGet()
	{
		return ll.removeLast(); //把要刪除的元素反出去。這樣可以保證把存進來元素一次取出
	}


	//添加一個判斷是否存在元素的函數
	public boolean isNull()
	{
		return ll.isEmpty();
	}


}


//寫一個堆棧
class DuiZhan
{
	private LinkedList ll;
	DuiZhan()
	{
		ll = new LinkedList();
	}


	//輸入元素
	public void myAdd(Object obj)
	{
		ll.addFirst(obj);
	}


	//獲取元素
	public Object myGet()
	{
		return ll.removeFirst();
	}


	//判斷是否爲空
	public boolean isNull()
	{
		return ll.isEmpty();
	}


}


class LinkedListTest 
{
	public static void main(String[] args) 
	{
		//調用堆棧
		duiZhan();
		//調用隊列
		duiLie();
	}
	
	//寫一個應用堆棧的函數
	public static void duiZhan()
	{
		DuiZhan d = new DuiZhan(); //創建一個容器
		d.myAdd("java03"); //輸入元素
		d.myAdd("java04");
		
		//獲取全部元素
		for( ; !d.isNull(); )
		{
			p(d.myGet());
		}
	}


	//寫一個應用隊列的函數
	public static void duiLie()
	{
		DuiLie d = new DuiLie();
		d.myAdd("java01"); //添加元素
		d.myAdd("java02");
		
		//獲取全部元素
		for( ; !d.isNull(); )
		{
			p(d.myGet());
		}
	}


	public static void p(Object obj)
	{
		System.out.println(obj);
	}
}












五、泛型:JDK1.5版本以後出現新特性,用於解決安全問題,是一個類型安全機制。
一、泛型


泛型的好處:
1,將運行時期出現問題ClassCastException(類型轉換異常)轉移到了編譯時期,
方便與程序員解決問題,讓運行時期問題減少,安全。
2,避免了強制轉換麻煩。

	//定義一個只能裝String類型的數據的容器
	ArrayList<String> al = new ArrayList<String>();
	al.add("java");
	al.add("jaasdfds");
	al.add("adfasf");


	Iterator<String> it = al.iterator(); //建立一個String類型的迭代器
	for( ; it.hasNext(); )
	{
		String s = it.next();
		System.out.println(s + "   " + s.length());
	}






泛型的格式:通過<>來定義要操作的引用數據類型。
在使用java提供的對象時,什麼時候寫泛型呢?
通常在集合框架中很常見。
只要見到<>就要定義泛型。


其實<>就是用來接收類型的。


當使用集合時,將集合中要存儲的數據類型作爲參數傳遞到<>即可。




示例代碼:


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


class GenericDemo 
{
	public static void main(String[] args) 
	{
		TreeSet<String> ts = new TreeSet<String>(new LenBi()); //創建一個String類型的容器
		ts.add("abd");
		ts.add("bc");
		ts.add("g");
		ts.add("ddd");
		ts.add("agdg");


		Iterator<String> it = ts.iterator(); //創建一個String類型的迭代器
		for( ; it.hasNext(); )
		{
			String s = it.next(); //把遍歷的元素賦值給變量s;
			System.out.println(s + "   " + s.length());
		}
	}
}

//定義一個比較長度的比較器 
class LenBi implements Comparator<String>  //定義一個判斷字符串長度的比較器
{
	public int compare(String s1, String s2)
	{
		int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
		if(num == 0)
		{
			return s1.compareTo(s2);
		}
		return num;
	}
}




六、泛型類


/*
泛型類
什麼時候定義泛型呢:
當類中要操作的引用數據類型不確定的時候,
早期定義Object來完成擴展。
現在定義泛型來完成擴展。
*/


class Worker
{
}


//沒有泛型之前的做法
class SetObject
{
	private Object obj;
	public void setObject(Object obj)
	{
		this.obj = obj;
	}


	public Object getObject()
	{
		return obj;
	}
}


//寫一個泛型類
class FanXing<QQ>
{
	private QQ q;
	public void setQQ(QQ q)
	{
		this.q = q;
	}
	
	public QQ getQQ()
	{
		return q;
	}
}


class GenericDemo1
{
	public static void main(String[] args) 
	{
		SetObject s = new SetObject();
		s.setObject(new Worker());
		Worker w = (Worker)s.getObject();
		//運用泛型
		FanXing<Worker> f = new FanXing<Worker>();
		f.setQQ(new Worker());
		Worker w1 = f.getQQ();
	}
}










七、泛型限定


?通配符。也可以理解爲佔位符。
泛型的限定:
? extends E: 可以接收E類型或者E的子類型。上限
? super E: 可以接收E類型或者E的父類型。下限
示例代碼:


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


class GenericSuper 
{
	public static void main(String[] args) 
	{
		//創建一個容器。只打印狗類
		TreeSet<Dog> d = new TreeSet<Dog>(new Comp());
		d.add(new Dog("小狗"));
		d.add(new Dog("老狗")); //給容器添加元素
		d.add(new Dog("中型狗"));


		//創建一個容納貓類的容器
		TreeSet<Cat> c = new TreeSet<Cat>(new Comp());
		c.add(new Cat("小貓"));
		c.add(new Cat("老貓")); //給容器添加元素
		c.add(new Cat("中年貓"));
		daYin(d); //調用函數打印元素
		daYin(c);
	}
	public static void daYin(TreeSet<? extends Animal> ts) //使用上限的方式對兩個容器元素進行輸出
	{
		Iterator<? extends Animal> it = ts.iterator(); 
		for( ; it.hasNext(); )
		{
			System.out.println(it.next().getName());
		}
	}
}


class Comp implements Comparator<Animal> //使用下限的形式創建了一個比較器
{
	public int compare(Animal a1, Animal a2)
	{
		return a1.getName().compareTo(a2.getName()); //按照自然順序把名字排列
	}
}


//創建一個動物類
class Animal
{
	private String name; //定義動物名字變量
	Animal(String name) //定義構造函數。讓其在建立對象的時候就設置好名字
	{
		this.name = name;
	}


	//設置名字
	public void setName(String name)
	{
		this.name = name;
	}


	//返回名字
	public String getName()
	{
		return name;
	}
}


//創建一個狗類
class Dog extends Animal
{
	Dog(String name) 
	{
		super(name);
	}
}
 //創建一個貓類
class Cat extends Animal
{
	Cat(String name)
	{
		super(name);
	}
}


---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Unity開發</a>、<a href="http://edu.csdn.net"target="blank">.Net培訓</a>、期待與您交流! ----------------------


詳細請查看:<a href="http://edu.csdn.net" target="blank">http://edu.csdn.net</a>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章