泛型
概念:
- 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
概述:
-
存在於java.util包中。
-
內部用數組存放數據,封裝了數組的操作,每個對象都有下標。
-
內部數組默認初始容量是10。如果不夠會以1.5倍容量增長。
-
查詢快,增刪數據效率會降低。
創建對象:
- 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
}
}