Java進階技術:泛型

泛型

概念:

  • public class LinkedList
  • extends AbstractSequentialList
  • implements List, Deque, Cloneable, java.io.Serializable{}
  • public interface Deque extends Queue {}
  • public interface Queue extends Collection {}
  • public interface Collection extends Iterable {}

我們上面的代碼中出現的<?>是什麼東西呢,它叫泛型,常用來和集合對象一同使用,所以我們在開始學習集合之前,必須先了解下什麼是泛型。而且泛型概念非常重要,它是程序的增強器,它是目前主流的開發方式。

泛型是(Generics)是JDK1.5 的一個新特性,其實就是一個『語法糖』,本質上就是編譯器爲了提供更好的可讀性而提供的一種小手段,小技巧,虛擬機層面是不存在所謂『泛型』的概念的。

作用:

  • 通過泛型的語法定義,約束集合元素的類型,進行安全檢查,把錯誤顯示在編譯期
  • 代碼通用性更強,後面有案例
  • 泛型可以提升程序代碼的可讀性,但它只是一個語法糖(編譯後這樣的東西就被刪除,不出現在最終的源代碼中),對於JVM運行時的性能是沒有任何影響的。

泛型聲明 :
泛型可以在接口、方法、返回值上使用:

  • java.util.List泛型接口/類:
    public interface Collection {}
  • 泛型方法的聲明:
    public void print(E e) {}
  • 在方法返回值前聲明瞭一個表示後面出現的E是泛型,而不是普通的java變量。

常用名稱:

  • E - Element (在集合中使用,因爲集合中存放的是元素)
  • T - Type(Java 類)
  • K - Key(鍵)
  • V - Value(值)
  • N - Number(數值類型)
  • ? - 表示不確定的java類型
public class Test1 {
    public static void main(String[] args) {
       int[] a = new int[3];
       a[0]=1;
       a[1]=2;   
       //int類型的數組,規定了數組裏的數據類型,類型不對就報錯。
//     a[2]="hello";       
       //1,泛型的標誌<>
       //2,泛型的好處:規定了數據的類型,不能想放什麼數據就放什麼類型,要遵守泛型規定的類型
       //3,泛型的數據類型只能是引用類型,不能是基本類型
       List<Integer> list = new ArrayList<Integer>();
       list.add(1);
       list.add(2);
       
//4,如果類型不對,把運行時期纔會 報的錯ClassCastException直接在編譯時期就報出來

//     list.add("a");
//     list.add('b');       
       Iterator it = list.iterator();
       while(it.hasNext()) {
           Integer s = (Integer) it.next();
           System.out.println(s);
       }      
    }
  • 代碼通用性更強
  • 傳統方式通過重載多態實現,方法同名,參數類型不同。
public class TestOldStyle {
    public static void print(Integer[] dArray) {
       for( Integer d : dArray) {
           System.out.println(d);
       }
    } 
    
    public static void print( String[] sArray) {
       for( String s : sArray) {
           System.out.println(s);
       }
    }   
    
    public static void main(String[] args) {
       Integer[] scores = new Integer[]{100,98,80};
       String[] names = new String[]{"語文","數學","英語"};      
       TestOldStyle.print(scores);
       TestOldStyle.print(names);
    }
}

泛型方式:

public class TestGenarics {
    public static <E> void print(E[] arr) {
       for(E e : arr) {
           System.out.println(e);
       }
    } 
    
    public static void main(String[] args) {
       Integer[] scores = new Integer[]{ 100,98,80 };
       String[] names = new String[]{ "語文","數學","英語" };
       Double[] moneys = new Double[] { 10.1,20.2,30.3 };      
       TestGenarics.print(scores);
       TestGenarics.print(names);
       TestGenarics.print(moneys);
    }
}

Collection接口

概述:

  • 英文名稱Collection,是用來存放對象的數據結構。其中長度可變,而且集合中可以存放不同類型的對象。並提供了一組操作成批對象的方法。
  • 數組的缺點:長度是固定不可變的,訪問方式單一,插入、刪除等操作繁瑣。

集合的繼承結構
在這裏插入圖片描述

>Collection接口

>-- List接口  : 數據有序,可以重複。

   -- ArrayList子類

   -- LinkedList子類

>-- Set接口  : 數據無序,不可以存重複值

   -- HashSet子類

>-- Map接口  : 鍵值對存數據

   -- HashMap

>-- Collections工具類
常用方法:
  • boolean add(E e):添加元素。
  • boolean addAll(Collection c):把小集合添加到大集合中 。
  • boolean contains(Object o) : 如果此 collection 包含指定的元素,則返回 true。
  • boolean isEmpty() :如果此 collection 沒有元素,則返回 true。
  • Iterator iterator():返回在此 collection 的元素上進行迭代的迭代器。
  • boolean remove(Object o) :從此 collection 中移除指定元素的單個實例。
  • int size() :返回此 collection 中的元素數。
  • Objec[] toArray():返回對象數組

List接口:

有序的 collection(也稱爲序列)。此接口的用戶可以對列表中每個元素的插入位置進行精確地控制。用戶可以根據元素的整數索引(在列表中的位置)訪問元素,並搜索列表中的元素。

特點:
1、 數據有序
2、 允許存放重複元素
3、 元素都有索引

常用方法:

ListIterator listIterator()

  •      返回此列表元素的列表迭代器(按適當順序)。
    

ListIterator listIterator(int index)

  •      返回列表中元素的列表迭代器(按適當順序),從列表的指定位置開始。
    

void add(int index, E element)

  •      在列表的指定位置插入指定元素(可選操作)。
    

boolean addAll(int index, Collection<? extends E> c)

  •      將指定 collection 中的所有元素都插入到列表中的指定位置(可選操作)。
    

List subList(int fromIndex, int toIndex)

  • 返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之間的部分視圖。
    

E get(int index)

  •      返回列表中指定位置的元素。  
    

int indexOf(Object o)

  •      返回此列表中第一次出現的指定元素的索引;如果此列表不包含該元素,則返回 -1。
    

ArrayList

概述:

  1. 存在於java.util包中。
    
  2. 內部用數組存放數據,封裝了數組的操作,每個對象都有下標。
    
  3. 內部數組默認初始容量是10。如果不夠會以1.5倍容量增長。
    
  4. 查詢快,增刪數據效率會降低。
    

創建對象:

  • new ArrayList():初始容量是10

測試常用方法:

public class Test3_AL {
       public static void main(String[] args) {
              ArrayList list = new ArrayList();
              list.add("aaa");//存入數據
              list.add("123");
              list.add("ccc");
              list.add("ddd");
              System.out.println(list);//list中內容
              System.out.println(list.size());//集合長度
              System.out.println(list.get(1));//根據下標獲取元素                     
              System.out.println();
              System.out.println(list.remove(2));//移除下標對應的元素
              System.out.println(list);   
                                
               //下標遍歷
	for (int i = 0; i < list.size(); i++) {
		System.out.print(list.get(i));
}
                     
       //Iterator迭代遍歷,封裝了下標
                     Iterator<String> it = list.iterator();
                     while (it.hasNext()) {//如果有數據
                            String s = it.next();//一個一個向後遍歷
                            System.out.println(s);
                     }      
         }
}

LinkedList

在這裏插入圖片描述
常用方法:

  • add() get()
  • size()
  • remove(i)
  • remove(數據)
  • iterator()
  • addFirst() addLast()
  • getFirst() getLast()
  • removeFirst() removeLast()

測試迭代器遍歷,雙向鏈表:下標遍歷效率低,迭代器遍歷效率高

public class tt {
       public static void main(String[] args) throws Exception {
              LinkedList ll = new LinkedList ();
              for (int i = 0; i < 100000; i++) {
                     ll.add(100);
              }
              f1(ll);
              f2(ll);
       } 
       private static void f2(LinkedList<Integer> ll) {
              long t = System.currentTimeMillis();
              Iterator it = ll.iterator();
              while(it.hasNext()) {
                     it.next();
              }
              t = System.currentTimeMillis()-t;
              System.out.println("=====iterator========="+t);//16
       } 
       private static void f1(LinkedList<Integer> ll) {
              long t = System.currentTimeMillis();
              for (int i = 0; i < ll.size(); i++) {
                     ll.get(i);
              }
              long t1 = System.currentTimeMillis();
              System.out.println("~~~~for~~~~~~~"+(t1-t));//9078
       }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章