天天看點

筆記筆記12

筆記12

課程内容
	1、集合的概述,體系結構
	2、單列集合Collection
	3、List有序的。ArrayList,LinkedList
	4、泛型
           

一、集合的概述

體系結構

1、集合分類:
	單列集合:每個元素都是一個單獨的個體。
	雙列集合:每個操作都是針對一對資料來進行的,一對資料作為一個整體。鍵值對。
2、單列集合的體系:
	Collection                      單列集合的頂層接口
		List                        有序的子接口
			ArrayList               順序存儲的實作類,查詢快,增删慢
			LinkedList              鍊式存儲,查詢慢,增删塊
		Set                         無序的子接口
			HashSet                 哈希表存儲
				LinkedHashSet       HashSet的子類
3、雙列集合的體系:
	Map                             雙列集合的頂層接口
		HashMap                     哈希表存儲Map的實作類
			LinkedHashMap           HashMap的子類
           

Collection的概述和常用方法

1、單詞:收集,集合
2、單列集合的頂層接口:定義的所有單列集合中共有的功能。
3、Collection是一個接口,不能執行個體化,不能建立對象,找一個該接口的實作類對象。
	使用接口類型的引用,指向實作類的對象
	Collection類型的引用,指向ArrayList類型的對象(隻能調用接口中的方法)
4、常用的方法
	add(Object obj):将obj這個元素添加到集合中
	remove(Object obj):将obj元素從集合中移除
	contains(Object obj)判斷集合中是否包含obj這個元素
	isEmpty()就是集合為空就傳回true
	size()傳回就是集合中元素的個數
	clear();清空集合中的元素
           
package com.ujiuye.homework;

import java.util.ArrayList;
import java.util.Collection;

public class Demo_1 {
	public static void main(String[] args) {
//		Collection 常用的方法
		Collection coll = new ArrayList();//		最終隻能調用父接口中的方法
//		向集合中添加資料,在添加元素的時候,如果添加的是基本資料類型,預設轉為包裝類類型
		coll.add(123);
		coll.add("hello");
		coll.add(1.2);
		coll.add(true);
		coll.add('a');		
		System.out.println(coll);
//		remove(Object obj):将obj元素從集合中移除
		coll.remove(true);
		System.out.println(coll);
//		contains(Object obj)判斷集合中是否包含obj這個元素
		System.out.println(coll.contains('a'));
		System.out.println(coll.contains('p'));
//		isEmpty()就是集合為空就傳回true
		System.out.println(coll.isEmpty());
//		size()傳回就是集合中元素的個數
		System.out.println(coll.size());
//		clear();清空集合中的元素
		coll.clear();
		System.out.println(coll);
		System.out.println(coll.isEmpty());
		System.out.println(coll.size());
	}
}
           

Collection集合的第一種周遊

1、轉成數組,通過周遊數組,來間接的通路集合
2、方法:Object[] toArray():将調用者集合轉成Object類型的數組
           
package com.ujiuye.demos;
import java.util.ArrayList;
import java.util.Collection;
public class Demo_2 {
	public static void main(String[] args) {
//		Collection集合的第一種周遊方式
		Collection coll = new ArrayList();
		coll.add(520);
		coll.add("成都");
		coll.add(true);
		coll.add(9.9);
		System.out.println(coll);
//		将集合轉成數組
		Object[] objs = coll.toArray();
//		周遊對象數組
		for (int i = 0; i < objs.length; i++) {
			System.out.println(objs[i]);
		}
	}
}
           

Collection中帶All的方法

1、addAll(Collection c):将參數c中的所有元素,都添加到調用者集合中
2、removeAll(Collection c):将參數集合c中的元素都從調用者集合中移除
3、containsAll(Collection c):判斷調用者集合中是否全部包含參數集合c中的元素
4、retainAll(Collection<?> c)  參數c中有哪些元素,就在調用者集合中保留哪些元素(參數c集合和調用者集合中共有的元素)
           
package com.ujiuye.demos;

import java.util.ArrayList;
import java.util.Collection;

public class Demo_3 {
	public static void main(String[] args) {
//		Collection中帶all的方法
//		
		Collection coll1 = new ArrayList();
		coll1.add("趙雲");
		coll1.add("關羽");
		coll1.add("張飛");
		System.out.println(coll1);
//		===========================
		Collection coll2 = new ArrayList();
		coll2.add(897);
		coll2.add(520);
		coll2.add(520);
		coll2.add(825);
		coll2.add(825);
		System.out.println("coll2 " + coll2);
//		addAll(Collection c):将參數集合c中的元素都添加到調用者集合中
		coll1.addAll(coll2);
		System.out.println("coll1:AddAll " + coll1);
		
//		containsAll(Collection c):判斷調用者集合中是否全部包含參數集合c中的元素
		System.out.println("containsAll: " + coll1.containsAll(coll2));
		
//		removeAll(Collection c):将參數集合c中的元素都從調用者集合中移除
		Collection coll3 = new ArrayList();
		coll3.add(825);
		coll3.add(520);
		coll3.add("張飛");
		System.out.println("coll3 : " + coll3);
		coll1.removeAll(coll3);‘ 
		System.out.println("coll1 :removeAll: " + coll1);
		System.out.println("====================================");
//		retainAll(Collection<?> c)  參數c中有哪些元素,就在調用者集合中保留哪些元素(參數c集合和調用者集合中共有的元素)
		Collection coll4 = new ArrayList();
		coll4.add(520);
		coll4.add("王祖賢");
		coll4.add("王祖藍");
		coll4.add("王寶強");
		System.out.println(coll4);
		Collection coll5 = new ArrayList();
		coll5.add(520);
		coll5.add("王祖賢");
		coll5.add("周潤發");
		coll5.add("馬蓉");
		System.out.println(coll5);
		coll4.retainAll(coll5);
		System.out.println(coll4);
	}
}
           

集合周遊的第二種方式:疊代器

1、疊代:更新疊代,從某一個到下一個的過程的含義
2、疊代器:專門用于将集合中的元素,一個到另一個逐個進行疊代的過程,就是提供一個方法對集合容器對象都進行通路。而又不去暴露對象容器的内部細節。集合容器内部結構不同,很多時候不知道怎樣去周遊一個容器中所有的元素是。是以為了容器中的元素操作起來更為簡單,java引入了疊代器模式,把通路不同邏輯從不同類型集合類中抽取出來,避免了向外部暴露集合内部的内部結構。
3、擷取:集合自己内部有一個可以疊代自己的對象,從集合中擷取即可
	Iterator iterator()
4、疊代器的使用:
	方法iterator()傳回是一個Iterator接口的實作類對象可以使用Iterator接口中提供的方法。
	hastNext():判斷集合中是否還有下一個元素
	next():擷取集合中的下一個元素,讓疊代器指針發生一次移動
	remove();删除疊代器正在周遊的那個元素
5、疊代器在使用時候的注意事項
	(1)疊代器對象雖然多次調用next方法,都是同樣的名稱,但是每次調用方法傳回的内容是不一樣的。
		next方法既可以擷取下一個元素,也會讓疊代器對象,向前移動一步。
	(2)如果沒有下一個元素,仍然調用next方法,出現NoSuchElementException(沒有目前元素異常)可以使用hasNext方法進行判斷,如果為true就調用next方法,為flalse就不調用next方法
	(3)hastNext方法不會移動疊代器指針的位置
	(4)next()會移動疊代器指針的位置
	(5)不要隻判斷一次hasNext方法,就調用多次next方法
           
package com.ujiuye.demos;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Demo_5 {
	private static final Object Person = null;
//	不要隻判斷一次hasNext方法,就調用多次next方法
	public static void main(String[] args) {
		Collection coll = new ArrayList();
		coll.add(new Person("張三", 23));
		coll.add(new Person("李四", 24));
		coll.add(new Person("王五", 25));
		coll.add(new Person("趙六", 26));
		coll.add(new Person("小七", 27));// <----
//		1、調用集合中的iterator()傳回了一個疊代器對象
		Iterator it = coll.iterator();
		while (it.hasNext()) {
//			不要隻判斷一次hasNext方法,就調用多次next方法
//			System.out.println(((Person)it.next()).getName() + " " + ((Person)it.next()).getAge());
			Object obj = it.next();
			Person p = (Person) obj;
			System.out.println(p.getName() + " " + p.getAge());
		}
	}
}
           

二、List

1、概述:
	是Collection有序的子接口
2、特點:
	有序:每個元素都有自己位置,不同的位置有差別的
	有索引:每個元素都有自己的編号
	可以重複:即使是值相同的元素,位置和索引是不同的,可以區分相同的值
3、特有方法:
	add(int index,Object obj): 在指定索引上,添加指定的元素
	remove(int index):删除指定索引上的元素
	set(int intdex,Object obj):将指定索引上的值,修改為指定的值
	get(int index):擷取指定索引上的值
           
package com.ujiuye.demos;

import java.util.ArrayList;
import java.util.List;

public class Demo_6 {
	public static void main(String[] args) {
//		List中特有的方法
		List list = new ArrayList();
//		add(int index,Object obj)
		list.add(0,123);//java,123,521
		list.add(1,521);
		list.add(0,"java");
		list.add("hello");
		System.out.println(list);
//		remove(int index)
		list.remove(1);
		System.out.println(list);
//		set(int index,Object obj)
		list.set(2, "約會");
		System.out.println(list);
//		get(int index);
		System.out.println(list.get(2));
	}
}

           

第三種周遊方式

1、針對就是List集合特有的周遊方式
2、可以通過集合中的size方法擷取集合中元素的個數,List集合有索引,結合get方法就能夠擷取List集合中所有的元素。
           
package com.ujiuye.demos;
import java.util.ArrayList;
import java.util.List;
public class Demo_7 {
//	第三種周遊方式
	public static void main(String[] args) {
		List list = new ArrayList();
//	    add(int index,Object obj)
		list.add(0, 123);// java,123,521
		list.add(1, 521);
		list.add(0, "java");
		list.add("hello");
		System.out.println(list);
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
	}

}

           

并發修改異常

1、ConcurrentModificationException
	并發修改異常
2、出現的原因:在使用【疊代器對象】周遊集合的同時,使用【集合對象】增加或删除集合的元素
3、避免的方式:兩種方式都是針對list集合
	方式1:疊代器周遊,疊代器增加
	方法2:集合周遊,集合增加
4、方式1:疊代器周遊,疊代器增加:問題普通的疊代器中沒有增加的方法,需要使用List中特有的疊代器	
	疊代器增加:問題普通的疊代器中沒有增加的方法,需要使用List中特有的疊代器
	清單疊代器:ListIterator是Iterator的子接口,擁有Iterator中所有的方法,還要特有的方法
	清單疊代器的擷取:listIterator();
   方式2:集合周遊,集合增加
   	list特有的周遊方式,size和get方法相結合
5、不是所有的集合在進行疊代器周遊,疊代器增删的時候都會出現并發修改異常
	集合中的倒數第二個元素是不會發生的,其他都是會發生了。
           
package com.ujiuye.demos;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class Demo_8 {
	public static void main(String[] args) {
		List list = new ArrayList();
		list.add("hello");
		list.add("java");
		list.add("php");
		list.add("C");
		list.add("Python");
		System.out.println(list);
		// 擷取清單疊代器對象

		Iterator it = list.iterator();
		while (it.hasNext()) {
			Object obj = it.next();
			// 判斷元素是否和java一樣,如果一樣了就添加一個元素go
			if (obj.equals("C")) {
				// 在使用【疊代器對象】周遊集合的同時,不能使用【集合對象】增加或删除集合的元素
				// list.add("go");
//				集合中的倒數第二個元素是不會發生的,其他都是會發生了。
				list.remove("java");
			}

		}
		System.out.println(list);
	}

	private static void solve_1(List list) {
		System.out.println("-----------解決方式1---------------------");
		解決方式1
		ListIterator lit = list.listIterator();
		while (lit.hasNext()) {
//			方式1:疊代器周遊,疊代器增加
			Object obj = lit.next();
			if (obj.equals("java")) {
//				疊代器增加
				lit.add("go");
//				list.add("go");
			}
		}

		System.out.println(list);
		System.out.println("-----------解決方式2---------------------");
//		集合周遊,集合增加
		for (int i = 0; i < list.size(); i++) {
			if (list.get(i).equals("java")) {
				list.add("go");
			}
		}
		System.out.println(list);
	}
}
           

三、List的實作類

1、概述
	List是一個接口,根據底層的實作方式不同,具有不同的實作類
2、ArrayList:數組實作,順序存儲
3、LinkedList:節點實作,鍊式存儲
           

ArrayList

1、也是List一個實作類
2、沒有特有方法
	存儲的方式數組實作,順序存儲
	通過實體記憶體位置的關系,來表述邏輯順序的相鄰
3、圖示
           
筆記筆記12

LinkedList

1、List的一個實作類
2、存儲方式:
	節點實作,鍊式存儲
	不通過實體位置的相鄰,來表示邏輯位置的相鄰
	每個元素都在一個節點中,節點除了元素資料本身以外,還需要存儲是下一個節點記憶體位址
3、圖示
           
筆記筆記12
4、特點:
	查詢速度慢,需要根據前面的節點來擷取後一個節點的位址,前面所有的節點都要通路一遍,節點越多,查詢速度就越慢
	增删速度快:增删一個元素,隻需要修改前後兩個節點的指針域即可,與集合的規模沒有關系
5、LinkedList中特有的方法
	addFirst(Object obj)在頭部添加元素
	addLast(Object obj)在尾部添加元素
	removeFirst()     移除頭部元素
	removeLast()     移除尾部元素
	getFirst()       擷取頭部元素
	getLast()        擷取尾部元素
           
package com.ujiuye.demos;
import java.util.ArrayList;
import java.util.LinkedList;
public class Demo_9 {
	public static void main(String[] args) {
		LinkedList ll = new LinkedList();
		ll.addFirst("hello");
		ll.addFirst("java");
		ll.addFirst("php");
		System.out.println(ll);
		ll.addLast("C");
		ll.addLast("GO");
		System.out.println(ll);
		ll.removeFirst();
		ll.removeLast();
		System.out.println(ll);
		System.out.println(ll.getFirst());
		System.out.println(ll.getLast());
	}
}
           

ArrayList和LinkedList在查詢或者增删元素時的效率比較(在頭部)

package com.ujiuye.demos;

import java.util.ArrayList;
import java.util.LinkedList;

public class Demo_10 {
	final static int NUM = 99999;

//	ArrayList和LinkedList在查詢或者增删元素時的效率比較(在頭部)
	public static void main(String[] args) {
		linkedListFind();
	}
//	LinkedList查詢元素
	public static void linkedListFind() {
		LinkedList alist = new LinkedList();
		for (int i = 0; i < NUM; i++) {
			alist.addFirst(i);
		}

		long start = System.currentTimeMillis();
		for (int i = 0; i < alist.size(); i++) {
			alist.get(i);
		}
		
		long end = System.currentTimeMillis();
		System.out.println("LinkedList查詢元素的時間:" + (end - start));
	}
	

//	//	ArrayList查詢元素
	public static void arrayListFind() {
//		 添加元素
		ArrayList alist = new ArrayList();
		for (int i = 0; i < NUM; i++) {
			alist.add(i);
		}
//		=========================
		long start = System.currentTimeMillis();
		for (int i = 0; i < alist.size(); i++) {
			alist.get(i);
		}
		long end = System.currentTimeMillis();
		System.out.println("ArrayList查詢元素的時間:" + (end - start));
	}
	
	
//	ArrayList在頭部添加元素
	public static void arrayListAdd() {
		long start = System.currentTimeMillis();
		ArrayList alist = new ArrayList();
		for (int i = 0; i < NUM; i++) {
			alist.add(0, i);
		}
		long end = System.currentTimeMillis();
		System.out.println("ArrayList添加元素的時間:" + (end - start));
	}

//	LinkedList在頭部添加元素
	public static void linkedListAdd() {
		long start = System.currentTimeMillis();
		LinkedList alist = new LinkedList();
		for (int i = 0; i < NUM; i++) {
			alist.addFirst(i);
		}
		long end = System.currentTimeMillis();
		System.out.println("LinkedList添加元素的時間:" + (end - start));
	}

//	//	ArrayList在頭部删除元素
	public static void arrayListDel() {
//		 添加元素
		ArrayList alist = new ArrayList();
		for (int i = 0; i < NUM; i++) {
			alist.add(i);
		}
//		=========================
		long start = System.currentTimeMillis();
		while (!alist.isEmpty()) {
			alist.remove(0);
		}
		long end = System.currentTimeMillis();
		System.out.println("ArrayList删除元素的時間:" + (end - start));
	}

//	LinkedList在頭部删除元素
	public static void linkedListDel() {

		LinkedList alist = new LinkedList();
		for (int i = 0; i < NUM; i++) {
			alist.addFirst(i);
		}

		long start = System.currentTimeMillis();
		while (!alist.isEmpty()) {
			alist.removeFirst();
		}
		long end = System.currentTimeMillis();
		System.out.println("LinkedList删除元素的時間:" + (end - start));
	}
}
           

四、泛型

1、泛型的概述和使用
2、泛型:廣泛的類型,在定義一個類的時候,類型中有些方法參數,傳回值類型不确定,就使用一個符号,來表示那些尚未确定的類型,這個符号就稱為泛型。
3、使用:對于有泛型類,在這些類型後面跟上了一個尖括号,尖括号中寫上泛型的确定類型的(在使用該類型建立對象的時候,就可以寫出具體類型)
4、泛型的好處:
	(1)提高了資料的安全性,将運作時的問題,提前暴露在編譯時期
	(2)避免向下轉型的問題
5、注意事項:
	(1)前後一緻:在建立對象的時候,指派符号前後中尖括号中的類型要一緻
	(2)泛型推斷:如果建立對象的時候,前面已經寫好了泛型,後面建立對象的類型就可以隻寫一個尖括号。“菱形泛型”
		jdk1.7特性
	(3)不能定義泛型數組,發生泛型擦除問題,失去了泛型存在的意義
           
package com.ujiuye.demos;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Demo_11 {
	public static void main(String[] args) {
//		沒有泛型的情況
		List list = new ArrayList();
		list.add(123);
		list.add("hello");
		list.add(43);
		
		Iterator it = list.iterator();
		while(it.hasNext()) {
			Object next = it.next();
//			String str = (String)next;
//			System.out.println(str);
		}
//		有泛型的情況/ 對于對于有泛型類,在這些類型後面跟上了一個尖括号,尖括号中寫上泛型的确定類型的(在使用該類型建立對象的時候,就可以寫出具體類型
		List<String> list2 = new ArrayList<>();
		list2.add("php");
//		list2.add(123);
		list2.add("java");
		List<Integer> list3 = new ArrayList<>();
		list3.add(123);
//		list3.add("hello");
		list3.add(345);
		Iterator<Integer> iterator = list3.iterator();
		while(iterator.hasNext()) {
			Integer next = iterator.next();
			System.out.println(next);
		}
	}
}

           

泛型類的定義

1、泛型類:帶着泛型的類
2、格式:
	class 類名<泛型類型1,泛型類型2,泛型類型3,....>{
	
	}
3、說明
	(1)類名後面跟着的泛型類型,是泛型的聲明,一旦泛型聲明出來,就相當于這個類型成為了已知類型,這個類型就可以在整個類中使用
	(2)泛型聲明的名稱:隻需要是一個合法的辨別符即可,通常我們使用單個大寫字母來表示。E,Q ,T,M,K,V
	(3)泛型确定的時機:将來在使用這個類,建立對象的時候
           
package com.ujiuye.demos;
import java.util.ArrayList;
public class FXclass<qq> {//qq泛型的聲明,是一個不确定的類型
	public ArrayList<qq> alist = new ArrayList<>();
	/*	ArrayList<String> alist1 = new ArrayList<>();
		
		public void add(String str) {
			alist1.add(str);
		}*/
	
	public void addData(qq t) {
		alist.add(t);
	}
	
	public qq getData() {
		return alist.get(0);
	}
}
           

泛型方法

1、在方法聲明中,帶着泛型聲明的方法,就是泛型方法
2、格式
	修飾符 <泛型的聲明1,泛型聲明2,。。。> 傳回值類型 方法名稱(參數清單){
	
	}
3、說明
	(1)在方法上聲明的泛型,可以在整個方法中使用,當做已知類型去使用
	(2)如果是非靜态方法,在方法上沒有任何泛型的聲明,可以使用類上聲明的泛型
	(3)如果是靜态方法,在方法上沒有任何泛型的聲明,不可以使用類上聲明的泛型,隻能在靜态方法上,聲明泛型
           
package com.ujiuye.demos;

import java.util.Arrays;

public class Demo_13 {
//泛型方法
	public static void main(String[] args) {
//		定義一個泛型方法,能夠交換任意類型數組中的兩個元素
		String[] strs = {"hello","java","C","Php"};
		swap(strs, 0, 1);
		System.out.println(Arrays.toString(strs));
//		---------------------------------------
		Integer[] arr = {1,2,3,4,5,6};
		swap(arr, 0, 3);
		System.out.println(Arrays.toString(arr));
	}
	
	public static <T> void swap(T[] arr,int index1,int index2) {
		T temp = arr[index1];
		arr[index1] = arr[index2];
		arr[index2] = temp;
	}
}

           

泛型的通配符《了解》

1、使用泛型的時候,沒有使用具體的泛型聲明T,而是使用了和聲明的某個泛型T有關的一類類型,就稱為泛型的通配符
三種形式
2、第一種形式,使用?來表示可以是任意的類型
	removeAll(Collection<?> c) 表示可以接受任意泛型類型的集合c
	作為該方法的參數,參數集合的泛型可以和調用者集合泛型E沒有任何關系
3、第二種形式,使用? extends E來表示某個泛型類型或是該泛型類型的子類
	addAll(Collection<? extends E> c) 表示的是參數集合c中的泛型,必須是調用者集合泛型E的子類類型或者是本類類型,作為該方法的參數
4、第三種形式:使用?super E來表示必須是某個泛型類型或者是該泛型類型的父類類型
	Arrays工具類中排序方法sort(T[] t,Comparator<? super T> c)
	T就是該方法的泛型,T表示的就是數組中元素的類型<? super T>,表示的是可以接受泛型的類型必須是T類型或者是T類型的父類類型
           
package com.ujiuye.demos;

import java.util.ArrayList;
import java.util.Collection;

public class Demo_14 {
	public static void main(String[] args) {
//		泛型的通配符
		Collection<CharSequence> coll1 = new ArrayList<CharSequence>();
		coll1.add("java");
		coll1.add("C");
		coll1.add("python");
		coll1.add("go");
		System.out.println(coll1);
		
		Collection<Integer> coll2 = new ArrayList<>();
		coll2.add(123);
		coll2.add(234);
		coll2.add(554);
		
//		removeAll(Collection<?> c) ?表示可以接受任意泛型類型的集合c
//		作為該方法的參數,參數集合的泛型可以和調用者集合泛型E沒有任何關系
		coll1.removeAll(coll2);
		System.out.println(coll1);
//		addAll(Collection<? extends E> c) 表示的是參數集合c中的泛型,必須是調用者集合泛型E的子類類型或者是本類類型,作為該方法的參數
//		coll1.addAll(coll2);//
		Collection<String> coll3 = new ArrayList<>();
		coll3.add("123");
		coll3.add("as");
		coll3.add("asdf");
		coll1.addAll(coll3);
//		
	}
}