泛型
JDK5新特性
1.泛型
a. 泛型的引出:
定義一個字符串數組:
String[] strArray = {"hello","world","java"};String[] strArray = {"hello","world","java",100};//報錯,
給集合中存儲了字符串類型和Integer類型,在最終遍歷完成之後,報異常,原因是有兩種類的元素,最終用String去接收,只能接受跟它相關的類型的元素!java提供了一種技術:叫泛型(JDK5以後的特性)這裏常出現的異常: java.lang.ClassCastException:類轉換異常
b.格式:
<數據類型> :引用類型
c.特點:
i.將運行時期的異常提前到了編譯期間。ii.不用在強制類型轉換了。iii.優化了程序設計,解決了一個黃色警告線的問題。
d.遍歷方式:
i.普通for循環,size()/get()方法。ii.Iterator iterator()iii.ListIterator listIterator()列表迭代器
import java.util.ArrayList; import java.util.Iterator; import java.util.ListIterator; public class Student { ...略 ...略 } public class Demo01 { public static void main(String[] args) { //創建集合對象 ArrayList<Student> a = new ArrayList<Student>(); //創建4個學生對象 Student s1 = new Student("Tom",21); Student s2 = new Student("Tom2",22); Student s3 = new Student("Tom3",23); Student s4 = new Student("Tom4",24); //添加 a.add(s1); a.add(s2); a.add(s3); a.add(s4); //方式1 for (int i = 0; i < a.size(); i++) { Student s = a.get(i); System.out.println(s.getName()+"---"+s.getAge()); } System.out.println("------------"); //方式2 Iterator<Student> t = a.iterator(); while(t.hasNext()){ Student s =t.next();//不需要強制類型轉換; System.out.println(s.getName()+"---"+s.getAge()); } System.out.println("------------"); //方式3 ListIterator<Student> tt = a.listIterator(); while(tt.hasNext()){ Student s = tt.next(); System.out.println(s.getName()+"---"+s.getAge()); } } } out: Tom---21 Tom2---22 Tom3---23 Tom4---24 ------------ Tom---21 Tom2---22 Tom3---23 Tom4---24 ------------ Tom---21 Tom2---22 Tom3---23 Tom4---24
e.泛型的分類:
i.泛型類ii.泛型接口iii.泛型方法iv.泛型高級通配符:
1)?:代表任意數據類型:可以是Object類型以及Java類2)? extends E:向下限定,要麼跟當前類型一樣,要麼是它的子類3)? super E:向上限定,保持當前類型一致,或者是他的父類
//將泛型定義在類上 class LeiDemo<T> { public void fun(T t){ System.out.println(t); } } //把泛型定義在方法上 class LeiFanDemo{ public <T> void fun(T t){ System.out.println(t); } } public class LeiTool { public static void main(String[] args) { // 沒有泛型的時候 LeiDemo l = new LeiDemo(); l.fun(100); l.fun(true); l.fun("hello"); System.out.println("----------"); // 創建工具類對象:已經將給數據類型給定了 LeiDemo<String> a = new LeiDemo<String>(); a.fun("HELLO"); System.out.println("----------"); LeiFanDemo b = new LeiFanDemo(); b.fun("hello"); b.fun(100); b.fun(true); } }
interface Inter <T>{ public abstract void fun(T t); } //第一種:知道了實現類的數據類型:數據類型明確 /*class InterDemo implements Inter<String>{ @Override public void fun(String t) { System.out.println(t); } }*/ /* //第二種情況:不明確數據類型不明確接口的數據類型是什麼 class InterDemo<T> implements Inter<T>{ @Override public void fun(T t) { System.out.println(t); } } //泛型接口測試類 public class InterTool { public static void main(String[] args) { //創建接口對象:接口多態 /*第一種 知道了實現類的數據類型:數據類型明確 Inter i = new InterDemo(); i.fun("String"); //第二種: Inter<String> i = new InterDemo<String>(); i.fun("hello"); Inter<Integer> ii = new InterDemo<Integer>(); ii.fun(100); } }
import java.util.ArrayList; import java.util.Collection; class Animal {} class Cat extends Animal{} class Dog extends Animal{} public class Demo01 { public static void main(String[] args) { //創建集合對象 //如果明確數據類型,要保證前後數據類型一致; Collection<Object> a = new ArrayList<Object>(); Collection<Animal> b = new ArrayList<Animal>(); Collection<Cat> c = new ArrayList<Cat>(); Collection<Dog> d = new ArrayList<Dog>(); //? 代表任意數據類型,可以是Object類以及Java類; Collection<?> a1 = new ArrayList<Object>(); Collection<?> b1 = new ArrayList<Animal>(); Collection<?> c1 = new ArrayList<Cat>(); Collection<?> d1 = new ArrayList<Dog>(); // ? extends E 向下限定 和當前類型一樣 或者 是它的子類 Collection<? extends Object> a2 = new ArrayList<Animal>(); Collection<? extends Animal> b2 = new ArrayList<Animal>(); Collection<? extends Animal> c2 = new ArrayList<Dog>(); Collection<? extends Animal> d2 = new ArrayList<Cat>(); // ? super E 向上限定,保持當前類型一致,或者是他的父類 Collection<? super Animal> c11 = new ArrayList<Animal>() ; Collection<? super Animal> c12 = new ArrayList<Object>() ; } }
f.泛型的應用場景:
定義在類(具體類或者抽象類),接口的後面.一般情況,在集合中使用居多!
2.增強型for
a.歸屬:
是for循環的一種。
b.格式:
for(數據類型(引用類型) 變量名:數組或集合的對象名){
使用該變量。
}
c.應用場景:
集合或者數組(int 類型(Integer)/String類型的居多)。
d.優點和缺點:
i.優點:簡化了數組和集合的遍歷。ii.缺點:增強型for循環的目標不能爲null,在使用前,進行非空判斷。在使用前,進行非空判斷。
e.給ArrayList集合存儲字符串並遍歷
i.普通for循環ii.迭代器:Iterator iterator()iii.列表迭代器:ListIterator listIterator():List集合iv.增強for循環
import java.util.ArrayList; import java.util.Iterator; public class Demo01 { public static void main(String[] args) { //創建ArrayList集合對象 ArrayList<String> a = new ArrayList<String>(); //添加元素 a.add("hello"); a.add("is"); a.add("me"); //方法一:size()/get()遍歷 for (int i = 0; i < a.size(); i++) { String s = a.get(i); System.out.println(s); } System.out.println("------------"); //方法二:迭代器遍歷 Iterator<String> t = a.iterator(); while(t.hasNext()){ String s = t.next(); System.out.println(s); } System.out.println("------------"); //增強型for for (String s : a) { System.out.println(s); } } } /* out: hello is me ------------ hello is me ------------ hello is me */
class Student{ private String name; private int age; public Student() { super(); } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return name+"---"+age; } //重寫equals方法 比較的是內容 @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } } import java.util.ArrayList; import java.util.ListIterator; public class Demo02 { public static void main(String[] args) { ArrayList<Student> a = new ArrayList<Student>(); a.add(new Student("Tom",21)); a.add(new Student("Jack",22)); a.add(new Student("Peter",23)); //方法一:size()/get()遍歷 for (int i = 0; i < a.size(); i++) { Student s = a.get(i); System.out.println(s); } System.out.println("------------"); //方法二:列表迭代器遍歷 ListIterator<Student> t = a.listIterator(); while(t.hasNext()){ Student s = t.next(); System.out.println(s); } System.out.println("------------"); //方法三:增強型for for (Student s : a) { System.out.println(s); } } } /* out: Tom---21 Jack---22 Peter---23 ------------ Tom---21 Jack---22 Peter---23 ------------ Tom---21 Jack---22 Peter---23 */
3.靜態導入(JDK5新特性)
a.可以導入到方法級別的導入
b.格式:
import static 包名.類名.方法名;例:import static java.lang.Math.abs;
c.注意事項:
i.類中的方法必須是靜態的。ii.如果要使用靜態導入,爲了防止在一個類中出現同名的方法,那麼調用的時候需要前綴來區別開來
import static java.lang.Math.abs; import static java.lang.Math.pow; import static java.lang.Math.sqrt; public class Demo01 { public static void main(String[] args) { //Math類的一個絕對值; System.out.println(Math.abs(-100)); System.out.println(Math.pow(2, 3)); System.out.println(Math.sqrt(4)); System.out.println("------"); //利用JDK5特性 靜態導入 System.out.println(abs(-100)); System.out.println(pow(3,2)); System.out.println(sqrt(4)); } } /*out: 100 8.0 2.0 ------ 100 9.0 2.0 */
4.可變參數(JDK5新特性)
a.如果我們在寫方法的時候,參數個數不明確,就應該定義可變參數。
b.格式:
修飾符 返回值類型 方法名(參數類型...變量){}
注意: i.該變量的其實是一個數組名
ii.如果一個方法有多個參數,並且有可變參數,可變參數必須在最後
public class Demo01 { public static void main(String[] args) { int a = 1; int b = 2; int c = 3; int d = 4; System.out.println(sum(a,b,c,d,5));//15 } public static int sum(int...a){ int sum = 0; for (int i = 0; i < a.length; i++) { sum+=a[i]; } return sum; } }
c.Arrays工具類的一個方法
public static <T> List<T> asList(T... a) 返回一個受指定數組支持的固定大小的列表,把數組轉成集合。注意:這個集合的長度不能改變。
5.練習:
a.集合的嵌套遍歷
import java.util.ArrayList; public class 集合嵌套遍歷 { public static void main(String[] args) { ArrayList<ArrayList<Student>> a = new ArrayList<ArrayList<Student>>(); ArrayList<Student> x = new ArrayList<Student>(); ArrayList<Student> y = new ArrayList<Student>(); ArrayList<Student> z = new ArrayList<Student>(); a.add(x); a.add(y); a.add(z); x.add(new Student("Tom1",21)); x.add(new Student("Tom2",22)); x.add(new Student("Tom2",23)); y.add(new Student("Peter1",21)); y.add(new Student("Peter2",20)); y.add(new Student("Peter3",22)); y.add(new Student("Peter4",23)); z.add(new Student("Ash1",21)); z.add(new Student("Ash2",23)); z.add(new Student("Ash3",25)); for (ArrayList<Student> student : a) { System.out.println(student); } } } /* out: [Tom1---21, Tom2---22, Tom2---23] [Peter1---21, Peter2---20, Peter3---22, Peter4---23] [Ash1---21, Ash2---23, Ash3---25] */
b.獲取10個1-20之間的隨機數,要求不能重複
import java.util.ArrayList; import java.util.Random; public class TestDemo { public static void main(String[] args) { //創建一個Random隨機數對象 Random r = new Random(); //創建一個ArrayList集合對象 ArrayList<Integer> array = new ArrayList<Integer>() ; //定義一個統計變量 int count = 0 ; //判斷統計變量是否是10個 while(count < 10){ //存在10個隨機數,獲取1-20之間的隨機數,使用隨機數的這個對象 int number = r.nextInt(20) +1 ; //判斷集合中是否存在該數據,不存在,添加數據,統計變量++ if(!array.contains(number)){ array.add(number) ; count ++; } } //遍歷集合 for(Integer i : array){ System.out.println(i); } } }