帶你走進java-第十四章.泛型,多參數方法object...,數組轉集合,Set接口-HashSet實現類(重點:去重)

泛型

1.泛型的概念:
  泛型: 標識着 集合中存儲元素的數據類型
  寫法: <數據類型(即泛型)>
// 泛型的寫法:
	// 創建一個集合 ,保存a b c d
	// E  泛型  Element(元素)
	// 注意:前後泛型的類型要保持一致(如果後面要填的話)
	// jdk1.7 菱形泛型
	// 後面泛型可以不填 默認和前面的一致  
	ArrayList<String> list = new ArrayList<>();
	list.add("a");
	list.add("b"); 
	list.add("c"); 
	list.add("d");
	// 利用迭代器遍歷
	// 迭代器泛型 表示集合中保存的元素類型 [與實現類中的泛型保持一致]
	Iterator<String> iterator = list.iterator();
	while(iterator.hasNext()){
		String next = iterator.next();
		System.out.println(next);
		// 如果是自己寫的類的對象,需要重寫toString()
	}   
2.泛型的好處
  1️⃣保證了數據的安全性 (提示你 方法中要傳入的數據類型)
  2️⃣避免了 向下轉型(類型強轉) [提示你 創建什麼類型的對象接受迭代器傳來的數據]
  3️⃣將運行時的錯誤 轉化成了編譯錯誤 [類型接受錯誤時,不需要運行報錯,直接提示]
//   創建集合 保存3學生
//   獲取集合中的第0個學生 並打印姓名

ArrayList<Student> list = new ArrayList<>();
list.add(new Student("東東", 16)); // 好處 1️⃣:提示你方法中傳入學生類對象
list.add(new Student("生生", 18));
list.add(new Student("柳柳", 20));
Object object = list.get(0);
Student student = (Student) object; // 好處 2️⃣:可以不用向下轉型,直接用學生類對象接受
// 好處 3️⃣:若接受對象不對,不用運行才報錯,直接報錯(一般在迭代器中比較明顯)
3.泛型的聲明
  1️⃣聲明位置:  類名(接口名)<泛型> 
     假如:Student<S>   此時S是佔位符
    注意: 泛型使用佔位符(英文字符)時 一般使用大寫字母
  2️⃣什麼時候 指定泛型的真正類型?
    創建對象時 會給泛型 賦值數據(對象)類型
// 舉例:泛型的聲明 與 指定數據類型

// 泛型的聲明位置 (Worker類中屬性的數據類型都爲W)
class Worker<W>{
	// 利用泛型 聲明成員變量
	private W w;
	// 聲明set/get方法
	public void setW(W w) {
		this.w = w;
	}
	public W getW() {
		return w;
	}
	// 成員方法
	public void fun(W w) {
		System.out.println(w);
		System.out.println("我是fun方法");
	}
	// 一個類中 可不可以有多個泛型?  可以
	// 需要在方法上 進行泛型的聲明
	// 這個泛型 將會在 該方法被調用的時候  被傳參(不一定是該類對象的屬性)賦值
	public<Y> void fun1(Y y) {
		System.out.println(y);
	}
	// 靜態方法   能不能使用  W  泛型 ?   不能
	// 當方法被調用時,泛型被賦值
	public static<Q> void fun2(Q q) {
		System.out.println(q);
	}
}
//  指定泛型的真正數據類型
// 此時泛型佔位符W  被賦值  String
	Worker<String> worker = new Worker<>();
	worker.setW("wangjun");
	System.out.println(worker.getW());
	worker.fun("少年強則中國強");
	worker.fun1('1'); // 傳入的參數是字符,該Y被賦值char
// 接口中的泛型

// 泛型接口
interface InterA<G>{
	public abstract void fun(G g);
}
// 泛型類型確定 可以在 接口的實現類上確定
class InterAImpl implements InterA<String>{
	@Override
	public void fun(String g) {
		// TODO Auto-generated method stub
		
	}
}

多參數方法(int … num)

int ... num (輸入int類型 從0到num)
可以接受多個 int類型值  相當於參數是一個數組[0,1,...num]
使用條件:只能在方法中使用,用作傳入參數
使用限制:1.方法的參數列表中 最多隻能有一個不定長度的參數
         2.不定長度的數組的位置必須是最後一個參數,不然無法編譯
調用方式兩種
1.傳入多個值  用逗號隔開
2.直接傳入數組
// 第一種方法(傳入多個值,逗號隔開)調用
注意:可以添加不同類型的參數,但是要放在前面,放在後面會報錯
		 (換句話說: int ... num 要放在最後面)
	public static void print(String str,int ... num) {
			// 遍歷(獲取你傳進來有幾個int值)
			for (int i = 0; i < num.length; i++) {
				System.out.println(num[i]);
			}
		}
// 第二種方法(輸入數組)隔開
	int[] arr = {2,3,4,5};
	print(" ",arr);

數組轉集合:Arrays.asList(數組名),記住用集合接收

// ❎ 錯誤的 原因:集合中只能放引用類型的數據,不能放基本數據類型
int[] array = {1,2,3,4,5};
List<int[]> list = Arrays.asList(array);
System.out.println(list);
// ✔️ 正確的 裝箱了	
Integer[] array1 = {1,2,3,4,5};
List<Integer> list1 = Arrays.asList(array1);
System.out.println(list1);
//  創建一個字符串數組 保存三個名字
//  將數組 轉成集合 
//  添加一個名字
String[] arr = {"東東","生生","柳柳"};
// 將數組 轉成 集合
List<String> list2 = Arrays.asList(arr);
System.out.println(list2);
// 添加名字
// UnsupportedOperationException
// 不支持操作異常
// 注意:該方法 轉完集合後 不支持對集合的長度修改
// list.add("花花");
// 該方法意義在於: 可以使用集合類中 其他方法
boolean b = list2.contains("生生");
System.out.println(b);

4.泛型在繼承中的應用: 將子類或本類放入集合中
//  前提: class Student extends Person
//  舉例:
    ArrayList<Person> list = new ArrayList<Person>();
    list.add(new Student()); // 添加子類
    list.add(new Person()); // 添加本類

去重刪除

一般兩種方法 1.for循環刪除  2.迭代器刪除
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("b");
list.add("c");
list.add("d");   [a,b,b,c,d] 刪除兩個b
// 1.for循環刪除
for (int i = 0; i < list.size(); i++) {
		String string = list.get(i);
		if (string.equals("b")) {
			list.remove(i--);
			// 刪除一個,其他的前移一位,若兩個連續,則只能刪除一個
			// --,是爲了循環在再進行一次,刪除下一個b
		}
}
System.out.println(list);

// 2.迭代器刪除
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
	String str = iterator.next();
	if (str.equals("b")) {
		iterator.remove();
	}
}
System.out.println(list);

集合工具類:Collection.swap(list,i,j) 交換位置

Set接口-HashSet實現類

1.HashSet實現類的特點: 無序  無角標  不可重複(繼承Set接口)
  自帶去重 (前提:對象地址重複,才能去重,不能根據屬性直接去重) 
2.HashSet集合的建立
// 創建Set集合  添加a a b b c c 
// 有序: 指的是存取的順序  存的順序就是取的順序
// 迭代器遍歷
HashSet<String> set = new HashSet<>();
set.add("f");
set.add("a");
set.add("a");
set.add("b");
set.add("b");
set.add("c");
set.add("c");
// 迭代器遍歷
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
	String string = (String) iterator.next();
	System.out.println(string);
}
結果:
a,b,c,f(無序)

3.Set的自動去重
HashSet<Man> set = new HashSet<>();
Man m1 = new Man("1",11);
Man m2 = new Man("1",11);
Man m3 = new Man("2",22);
Man m4 = new Man("2",22);
Man m5 = new Man("3",33);
Man m6 = new Man("3",33);
set.add(m1);
set.add(m2);
set.add(m3);
set.add(m4);
set.add(m5);
set.add(m6);
Iterator<Man> iterator = set.iterator();
while (iterator.hasNext()) {
	Man m = (Man) iterator.next();
	System.out.println(m);
}
直接輸出結果: 一個沒刪            
沒去重原因:
// 系統每創建一個對象 都會爲這個對象
// 分配一個 hashCode值
// 當向HashSet集合中 保存對象時
// 系統會先比較hashCode值是否相同

// 相同: 再調用對象的equals方法進行比較,
//      如果equals方法比較也相同,那麼就不存
//      反之,會存儲到集合中
       
// 不相同: 如果HashCode不相同,就相當於不是一個對象
//	      那麼直接就把該對象 直接存入集合中
//	      也不會調用equals方法

解決辦法:
// 重寫hashCode和equals方法
// 舉例

/*
* 隨機10個數  [10,20] 裝到集合中去重
* Integer可以直接去重
* String可以直接去重
* 系統已經重寫好了hashCode()方法和equals()方法
* 自己寫的類沒有寫好,所以自己要重寫
*/
		HashSet<Integer> set  = new HashSet<>();
		for (int i = 0; i < 10; i++) {
			int num = (int)(Math.random() * 11 + 10);
			set.add(num);// 自動裝箱
		}
		System.out.println(set);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章