初識集合和泛型
阿新 • • 發佈:2017-06-20
1.8 聲明 編譯器 變化 泛型類 ise 個數 bre 重復元素
package com.oracle.Test; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /* * 問題: 你們怎麽理解集合這個詞. * 答: 通常指容器.用來裝載n個數據. * * 問題: 集合中能放的元素類型 * 答: Java設計人員.設計Java中的集合時.是希望這個集合可以放下所有類型的數據. * Java中有一個類是所有類的父類.Object.按照繼承和多態的理念.放Object可以代表 * 所有類型的數據.那麽放入沒有問題.但是再取出時要由大轉小.需要強轉.那麽這就會 * 遇到一個問題.ClassCastException(類型轉換異常.)這個異常是在引用數據類型 * 大轉小時.很容易產生的.如果想避免這個問題.需要使用instanceof 或者對象.getClass * ==類.class 來驗證數據類型是否匹配.(判斷對象屬不屬於某個類型) * * JDK在1.5的時候借鑒C++中模版這一概念在Java中引入了泛型. * * 問題:什麽是泛型 * 答: 簡單說就是類型參數化.要求一個容器中保存的數據類型是一致的.寫法是 * 容器<T> T代表這個容器要保存的數據類型. * * 總結:Java中的所有括號 * 1. { } 代表各種作用域. 類體 方法體 循環體 判斷體 * 靜態域 代碼塊 * 2. ( ) 遇到小括號代表方法. * 3. [ ] 數組 * 4. < > 泛型 * * 泛型可以寫成泛型類 : 在類名後<T> T語法上可以被其它 * 英文替換.我們習慣都使用T * 泛型可以寫泛型變量 * T t; 是跟隨泛型類的 * 泛型可以寫泛型方法.有兩個地方可以寫泛型 * 1.參數 也是和泛型類掛鉤的. * 2.返回值 * * public <T>void method(){ * } * * * 泛型的使用註意點: * 1.泛型的尖括號內只支持引用數據類型.如果想放 * 源生數據類型,需要使用對應的包裝類. * * 2.不推薦使用泛型類.C++中模版是可以被繼承的.但是 * Java中泛型是可擦除的.即在父類中設計了泛型.子類在繼承時 * 如果沒有顯示的提供泛型.父類的泛型可以被不繼承.如果 * 一定要使用泛型類那麽在遇到繼承時要在子類中提供一個構造 * 方法(帶有泛型的).強制要求子類繼承父類的泛型. * 目前泛型依然可以使用的是泛型方法. * * * 集合: * 1.集合是可變長度,因此在聲明時不需要像數組那樣指明長度 * 2.集合產看長度用的size()方法.獲取的是集合中元素的個數. * * 補充: * 1.接口和接口之間只有繼承關系.因為實現一個接口要把接口中所有 * 抽象內容具體化.而接口本身只能提供聲明. * * 2.接口可以繼承多個接口.而class(類)只能單繼承.所以Java被叫做 * 單繼承,多實現. * * 3.接口是對外的.所有接口中不可以有私有內容. * * * **/ public class Test { //Ctrl + Shift + T Open Type public static void main(String[] args) { /* * SRP 職責單一 方法 * LSP 裏氏替換 繼承 * OCP 開閉原則 抽象類 * DIP 迪米特方法則 .依賴倒置原則 - 面向接口編程 * ISP 接口職責單一 * * 這裏的警告是因為Collection接口上有泛型..編譯器會 * 檢查類型因此.因此需要提供 * * 在JDK1.8之前使用泛型時前後兩邊都要寫 * 在JDK1.8以後可以省略後面的泛型. * **/ Collection<String/*只要是引用數據類型都行*/> list = new ArrayList<String>(); //--註意size是方法 System.out.println(list.size()); //0 System.out.println(list.isEmpty()); //true /* *通過add方法向集合中添加元素.當集合因為調用該方法 *而發生改變時會返回true.其它情況返回false*/ System.out.println(list.add("Hello")+" 變化1"); //list = list.add("World"); 這是錯誤的,因為 list.add("World")的返回值是boolean型 System.out.println(list.add("World")+" 變化2"); //list.add("World"); //--以下代碼是否會產生死循環.是否會產生異常.會產生什麽異常. /*for(int i = 0 ;i < list.size() ;i ++){ list.add(i+""); }*/ // 不是死循環,但會產生異常 int類型最大值是會產生異常 //--判斷是否包含指定的對象.參數是對象. System.out.println(list.contains("Hello")+"包含指定對象1"); System.out.println(list.contains("World")+"包含指定對象2"); //--需要註意的是.這裏的返回值是Object[] 不可以轉變成 //--其它類型..如果轉換會產生ClassCastException Object[] array = list.toArray(); for (Object object : array) { System.out.println (object+" "); } //輸出 Hello World System.out.println(list.remove("World") ); //輸出 true System.out.println(list.size()); //輸出 1 Collection<String> other = new ArrayList<>(); other.add("World"); //--不會覆蓋之前的..ArrayList是允許有重復元素的. other.add("Hello"); other.add("!"); list.addAll(other); System.out.println(list.size()); //輸出 4 for (String string : list) { System.out.println(string); } list.remove("!"); list.add("ABC"); list.add("DEF"); list.add("!"); /* * list : Hello World Hello ! * other : World Hello ! * * 判斷是否包含全部元素.這個比較和順序無關. * */ System.out.println(list.containsAll(other)); //輸出 true } //-- 自己寫判斷包含全部的原型 public static boolean isContainsAll(Collection c1,Collection c2){ boolean result = true; //--1.參數檢查 //--2.確定誰大誰下 if(c1.size() >= c2.size()){ //--2.對第一個集合進行遍歷 for (Object obj : c2) { //--將每一個元素在c2中判斷是否包含 if(c1.contains(obj)){ result = true; continue; }else{ result = false; break; } } } return result; } /** * 想把c2中的內容都加到c1中. * @param c1 * @param c2 */ public void addAll(Collection<String> c1,Collection<String> c2){ //--1.檢查參數 //--2.遍歷C2.利用叠代器對集合進行遍歷. Iterator<String> iter = c2.iterator(); //--3.利用叠代器中已有API來判斷是否有下一個元素 while(iter.hasNext()){ //hasNext() 如果仍有元素可以叠代則返回true,其他返回false. //--4.通過叠代器取值 String temp = iter.next();//--返回值的類型會根據泛型自動改變 next() 返回叠代的下一個元素 c1.add(temp); } } }
初識集合和泛型