第50節:Java當中的泛型

標題圖
Java當中的泛型
01
import java.util.ArrayList; import java.util.List; public class Demo{ public static void main(String[] args){ // 建立list集合 List list = new ArrayList(); // 特性為長度可變,可以儲存物件(物件可以是任意的) list.add("abcdefg"); // 為物件 list.add(1); // 為物件 // 迴圈取出物件 for(Iterator it = list.iterator(); it.hasNext(); ){ Object object = (Object) it.next(); System.out.println(object.toString()); } // 列印字串的長度 // 因為字串的長度是字串的特有方法,所以需要進行轉型 String str = (String) it.next(); System.out.println(str.length()); } }
String str = (String) it.next(); System.out.println(str.length()); // 導致錯誤 java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String // 因為儲存的物件有Integer型別不能轉換為String型別
這就存在一個問題,如果集合儲存元素時,而且儲存物件有很多,而且物件型別不相同,就很容易導致隱患。
在 Java
中該檔案 xxx.java
在編譯的時候不會出現錯誤是因為該儲存的是 Object
的任何型別的物件,所以不會出現錯誤,編譯通過了。編譯後為 xxx.class
到執行。
如果要解決問題,可以把問題提前到編譯的時候去解決,讓集合更加安全,但是如何解決呢?
在集合中儲存的型別是可以任意的,所以會導致留下隱患,我們認識的陣列在儲存的時候就不會出現這種錯誤,因為它一開始就明確了儲存的記憶體型別,一旦不是它要儲存的型別就會編譯不過去導致出錯。
在集合中,我們可以一開始就明確要在容器中儲存的什麼型別的元素,跟陣列一樣就好了啊!那就不會出現 ClassCastException
的問題啦!
那麼如何建立集合,規定儲存定義的型別呢?這就需要有泛型了,有了泛型,就可以保證安全機制了,可以將執行時期轉移到編譯時期,泛型的出現就是為了給編譯使用的,泛型的出現就可以不用強轉了。
List<String> list = new ArrayList<String>();
泛型類運用
一直以來,你看到的 <E>
,就是所謂的泛型表達
java.util 介面 Collection<E>
泛型案例
public class Demo{ public static void main(String[] args){ // 新增泛型 Set<String> set = new TreeSet<String>(); // 新增元素 set.add("a"); set.add("ab"); for(Iterator<String> it = set.iterator(); it.hasNext();){ // 不用轉換了 String str = it.next(); System.out.println(str); } } }
進行比較長度:
Set<String> set = new TreeSet<String>(new Comperator>(){ @Override public int compare(String o1, String o2){ int temp = o1.length() - o2.length(); return temp == 0 ? o1.compareTo(o2) : temp; } }
泛型類 可能導致 ClassCastException
// 簡書作者:達叔小生 public static void main(String[] args){ Demo d = new Demo(); d.setObject(23); String s = (String) d.getObject(); System.out.println(s); }
class Demo{ private String str; public String getStr(){ return str; } public void setStr(String str){ this.str = str; } } // Object class Demo{ private Object object; public Object getObject(){ return object; } public void setObject(Object object){ this.object = object; } }
02
JDK1.5
開始的新技術
// 泛型類-泛型定義在類上 class Demo(D){ private D object; public D getObject(){ return object; } public void setObject(D object){ this.object = object; } }
Demo<String> d = new Demo<String>(); d.setObject("abc"); // 只能傳遞String型別 String s = d.getObject(); System.out.println(s);
泛型方法的使用
// 簡書作者:達叔小生 class Demo<D>{ public <D> void show(D d){ // 泛型方法 System.out.println("show"+d); } public static<E> void print(E e){ // 方法為靜態,使用泛型,需要定義在方法上 System.out.println("print"+d); } }
public static void mian(String[] args){ Demo<String> demo = new Demo<String>(); demo.show("abc"); demo.print("abc"); }
泛型介面
// 簡書作者:達叔小生 interface Inter<E>{ void show(E e); }
class InterDemo implements Inter<String>{ ... } class InterDemo<T> implements Inter<T>{ public void show(T t){ ... } }
泛型萬用字元
public class Demo{ public static main(String[] args){ List<Student> list = new ArrayList<Student>(); list.add(new Student("dashu",20)); list.add(new Student("dashu1",21)); list.add(new Student("dashu2",22)); for(Iterator<Student> it = list.iterator(); it.hasNext();){ System.out.println(it.next()); } // 列印 private static void print(Collection<Student> coll){ for(Iterator<Student> it = coll.iterator(); it.hasNext();){ System.out.println(it.next()); } // 列印 private static void printList(Collection<?> coll){ for(Iterator<?> it = coll.iterator(); it.hasNext();){ System.out.println(it.next().toString()); } // 列印 private static void printList(Collection<? extends Person> coll){ for(Iterator<? extends Person> it = coll.iterator(); it.hasNext();){ Person p = it.next(); System.out.println(p.getName()); } } } } }
? extends E
:接收 E
型別或者 E
的子型別
? super E
:接收 E
型別或者 E
的父型別
// 簡書作者:達叔小生 public class Person{ // 定義屬性 private String name; private int age; // 定義構造方法 public Person(){ super(); } // 有參的構造方法 public Person(String name, int age){ super(); 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; } // toString @Override public String toString(){ return "Person [ name=" + name + ",age=" + age + "]"; } }
public class Student extends Person{ public Student(){ super(); } public Student(String name, int age){ super(name,age; } @Override public String toString(){ return "Student [getName()=" + getName() + ",getAge()=" + getAge() + "]"; } }
public class Worker extends Person{ public Worker(){ super(); } public Worker(String name, int age){ super(name, age); } @Override public String toString(){ return "Worker [name =" + getName() + ", age =" + getAge() + "]"; } }
萬用字元的體現
Collection<String> c1 = new ArrayList<String>(); c1.add("dashu"); Collection<String> c2 = new ArrayList<String>(); c2.add("dashucoding"); boolean b = c1.containsAll(c2); // boolean containsAll(Collection<?> c); System.out.println("b="+b); // 結果為 false
內原始碼
// 簡書作者:達叔小生 public boolean containsAll(Collection<?> c){ for(Object o : c){ if(!contains(o)){ return false; } return true; } }
java.util 類 TreeSet<E> java.lang.Object -> java.util.AbstractCollection<E> -> java.util.AbstractSet<E> -> java.util.TreeSet<E> 引數E:為此set要維護的元素型別
public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>,Cloneable,Serializable
TreeSet
的構造方法
方法 | 說明 |
---|---|
TreeSet() | 構造方法,更具元素自然排序 |
TreeSet(Collection<? extends E> c) | 構造一個包含 collection 元素的新 TreeSet ,按照其元素自然順序進行排序 |
TreeSet(Comparator<? super E> comparator) | 構造一個新的空 TreeSet ,它根據指定比較進行排序 |
TreeSet(Sorted<E> s) | 構造一個有序的 set ,具有相同的對映關係與相同排序的 TreeSet |
public class Person implements Comparable<Person> { // 定義屬性 private String name; private int age; // 定義構造方法 public Person(){ super(); } // 有參的構造方法 public Person(String name, int age){ super(); 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; } // toString @Override public String toString(){ return "Person [ name=" + name + ",age=" + age + "]"; } @Override public int compareTo(Person o){ int temp = this.age - o.age; return temp == 0?this.name.compareTo(o.name) : temp; return 0; } }
Collection<Person> c = new ArrayList<Person>(); c.add(new Person("dashu",12)); c.add(new Person("dashucoding",13)); TreeSet<Person> ts = new TreeSet<Person>(c); ts.add(new Person("dashuxiaosheng",14)); for(Iterator<Person> it = ts.iterator(); it.hasNext();){ Person person = it.next((); System.out.println(person); }
// 簡書作者:達叔小生 TreeSet<Student> ts = new TreeSet<Student>(new ComparetoName() ); ts.add(new Student("dashu",12)); ts.add(new Student("dashucoding",13)); for(Iterator<Student> it = ts.iterator(); it.hasNext();){ Student student = it.next(); System.out.println(student); }
class ComparetoName implements Comparator<Student>{ @Override public int compare(Studento1, Student o2){ int temp = o1.getName().compareTo(o2.getName()); return temp == 0 ? o1.getAge() - o2.getAge() : temp; } }
ArrayList<Dog> a = new ArrayList<Dog>(); // 可以 ArrayList<Object> a = new ArrayList<String>(); // 不可以
泛型的特點
public class Demo{ public static void main(String[] args){ // 獲取集合中的最大值元素 Collection c = new ArrayList(); c.add(new Student("da",12)); c.add(new Student("dashu",13)); c.ass(new Student("dashucoding",14)); Student stu = getMax(c); System.out.println(stu); } public static Student getMax(collection<Student> c){ Iterator<Student> it = c.iterator(); Student max = it.next(); while(it.hasNext()){ Student temp = it.next(); if(temp.compareTo(max) > 0){ max = temp; } } return max; } }
// 簡書作者:達叔小生 public static <T extends Comparable<? super T>> T getMax(Collection<? extends T> c){ Iterator<? extends T> it = c.iterator(); T max = it.next(); while(it.haxNext()){ T temp = it.next(); if(temp.compareTo(max)>0){ max = temp; } } }
Collections
工具類
java.util 類 Collections java.lang.Object -> java.util.Collections
public class Collections extends Object
public class CollectionsDemo{ // 集合框架中的操作集合物件的工具類,靜態的方法 Collection<String> c = new ArrayList<String>(); c.add("dashu"); c.add("dashucoding"); String max = Collections.max(c); }
max public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)
原始碼
// 簡書作者:達叔小生 public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll){ Iterator<? extends T> i = coll.iterator(); T candidate = i.next(); while(i.hasNext()){ T next = i.next(); if(next.compareTo(candidate) > 0){ candidate = next; } return candidate; } }
max public static <T> T max (Collection<? extends T> coll,Comparator<? super T> comp) // 可以根據比較器產生順序
Collection<String> c = new ArrayList<String>(); c.add("dashu"); c.add("dashucoding"); String max = Collections.max(c, new Comparator<String>(){ @Override public int compare(String o1, String o2){ int temp = o1.length() - o2.length(); return temp == 0?o1.compareTo(o2) : temp; } });
原始碼
public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp){ if(comp == null){ return (T)max((Collection<SelfComparable>)(Collection) coll); Iterator<? extends T> i = coll.iterator(); T candidate = i.next(); while(i.hasNext()){ T next = i.next(); if(comp.compare(next, candidate) > 0) candidate = next; } return candidate; } }
排序
List<String> llist = new ArrayList<String>(); list.add("a"); list.add("add"); list.add("sl"); list.add("dljf"); Collections.sort(list);
長度排序
public class ComparatorLength implements Comparator<String>{ @Override public int compare(String o1, String o2){ int temp = o1.length() - o2.length(); return temp == 0 ? o1.compareTo(o2) : temp; } }
集合和陣列
public class ArraysDemo{ public static void main(String[] args){ int[] arr = {23,434,575}; System.out.println(Arrays.toString(arr)); String[] strs = {"dashu","da","shu"}; List<String> list = Arrays.asList(strs); System.out.println(list); } }
往後餘生,唯獨有你
簡書作者:達叔小生
90後帥氣小夥,良好的開發習慣;獨立思考的能力;主動並且善於溝通
簡書部落格: ofollow,noindex">https://www.jianshu.com/u/c785ece603d1
結語
- 下面我將繼續對 其他知識 深入講解 ,有興趣可以繼續關注
- 小禮物走一走 or 點贊