1. 程式人生 > >初識集合和泛型

初識集合和泛型

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); } } }

初識集合和泛型