第50節:Java的當中的泛型

来源:https://www.cnblogs.com/dashucoding/archive/2018/09/27/9711191.html
-Advertisement-
Play Games

Java當中的泛型 01 這就存在一個問題,如果集合存儲元素時,而且存儲對象有很多,而且對象類型不相同,就很容易導致隱患。 在 中該文件 在編譯的時候不會出現錯誤是因為該存儲的是 的任何類型的對象,所以不會出現錯誤,編譯通過了。編譯後為 到運行。 如果要解決問題,可以把問題提前到編譯的時候去解決,讓 ...


標題圖

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 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(Student  o1, 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後帥氣小伙,良好的開發習慣;獨立思考的能力;主動並且善於溝通
簡書博客: https://www.jianshu.com/u/c785ece603d1

結語

  • 下麵我將繼續對 其他知識 深入講解 ,有興趣可以繼續關註
  • 小禮物走一走 or 點贊

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 如果在控制項配置裡面設置了queueLimit屬性為1,就是隊列文件個數為1,並且在<input>標簽設置里multiple屬性。 在IE瀏覽器上傳附件的時候,瀏覽器會報錯“SCRIPT5007: 無法獲取未定義或 null 引用的屬性“replaceChild”。 解決辦法:在設置queueLimi ...
  • 最近寫了一個限流的插件,所以避免不了的接觸到了一些限流演算法。本篇文章就來分析一下這幾種常見的限流演算法 分析之前 計數器演算法 這個演算法可以說是限流演算法中最簡單的一種演算法了。 計數器演算法的意思呢就是當介面在一個時間單位中被訪問時,我就記下來訪問次數,直到它訪問的次數到達上限。 當一個請求過來時,我們就會 ...
  • 今年有人提出了2018年微服務將瘋狂至死,可見微服務的爭論從未停止過。在這我將自己對微服務的理解整理了一下,希望對大家有所幫助。 1.什麼是微服務 1)一組小的服務(大小沒有特別的標準,只要同一團隊的工程師理解服務的標識一致即可) 2)獨立的進程(java的tomcat,nodejs等) 3)輕量級 ...
  • 本文長度為2042字,建議閱讀6分鐘。所有「」包裹的文字,只對第一次出現進行高亮顯示。 閱讀目錄 「高可用」的作用? 如何來衡量「高可用」 做「高可用」的本質 結語 「高可用」的作用? 如何來衡量「高可用」 做「高可用」的本質 結語 「高可用」的作用? 如何來衡量「高可用」 做「高可用」的本質 結語 ...
  • 一.準備工作 準備3台機器,這樣才能完成分散式集群的實驗,當然能有更多機器更好: 192.168.3.64(e1) 192.168.3.62 (e2) 192.168.3.63(e3) 角色劃分: 3台機器全部安裝jdk1.8,因為elasticsearch是java開發的 3台全部安裝elasti ...
  • 教程:一:字典的創建 1:字典的介紹 >d = {key1:value1, key2:values2} (1)dictionary(字典) 是 Python 中最有用的數據類型。字典是無序的對象集合 (2)字典當中的元素是通過鍵來存取的,而不是通過偏移存取。 (3)字典是一種映射類型,它是一個無序的 ...
  • 美國時間 09 月 25 日,Oralce 正式發佈了 Java 11,這是據 Java 8 以後支持的首個長期版本。 為什麼說是長期版本,看下麵的官方發佈的支持路線圖表。 可以看出 Java 8 擴展支持到 2025 年,而 Java 11 擴展支持到 2026 年。 現在大部分都在用 Java ...
  • 程式員應該將核心關註點放在業務上,而不應該將時間過多的浪費在CRUD中,多數的ORM框架都把增加、修改與刪除做得非常不錯了,然後資料庫中查詢無疑是使用頻次最高、複雜度大、與性能密切相關的操作,我們希望得到一種使用方便,查詢靈活的ORM框架,MyBatis可以滿足這些要求,MyBatis是一個支持普通 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...