百度網(wǎng)盟推廣怎么選擇投放網(wǎng)站網(wǎng)絡推廣引流是做什么的
什么是 List
在集合框架中, List 是一個接口,繼承自 Collection 。

Collection 也是一個接口 ,該接口中規(guī)范了后序容器中常用的一些方法,具體如下所示:

Iterable 也是一個接口,表示實現(xiàn)該接口的類是可以逐個元素進行遍歷的,具體如下:

站在數(shù)據(jù)結構的角度來看, List 就是一個線性表,即 n 個具有相同類型元素的有限序列,在該序列上可以執(zhí)行增刪 改查以及變量等操作 。
常見接口介紹
List 中提供了好的方法,具體如下:

雖然方法比較多,但是常用方法如下:
方法 | 解釋 |
boolean add(E e) | 尾插 e |
void add(int index, E element) | 將 e 插入到 index 位置 |
boolean addAll(Collection<? extends E> c) | 尾插 c 中的元素 |
E remove(int index) | 刪除 index 位置元素 |
boolean remove(Object o) | 刪除遇到的第一個 o |
E get(int index) | 獲取下標 index 位置元素 |
E set(int index, E element) | 將下標 index 位置元素設置為 element |
void clear() | 清空 |
boolean contains(Object o) | 判斷 o 是否在線性表中 |
int indexOf(Object o) | 返回第一個 o 所在下標 |
int lastIndexOf(Object o) | 返回最后一個 o 的下標 |
List<E> subList(int fromIndex, int toIndex) | 截取部分 list |
List的使用
注意: List 是個接口,并不能直接用來實例化
如果要使用,必須去實例化 List 的實現(xiàn)類。在集合框架中, ArrayList 和 LinkedList 都實現(xiàn)了 List 接口 。
線性表
線性表(linear list)是n個具有相同特性的數(shù)據(jù)元素的有限序列。 線性表是一種在實際中廣泛使用的數(shù)據(jù)結 構,常見的線性表:順序表、鏈表、棧、隊列...
線性表在邏輯上是線性結構,也就說是連續(xù)的一條直線。但是在物理結構上并不一定是連續(xù)的,線性表在物 理上存儲時,通常以數(shù)組和鏈式結構的形式存儲。
順序表
順序表是用一段 物理地址連續(xù) 的存儲單元依次存儲數(shù)據(jù)元素的線性結構,一般情況下采用數(shù)組存儲。在數(shù)組上完成 數(shù)據(jù)的增刪查改。

ArrayList 簡介
在集合框架中, ArrayList 是一個普通的類,實現(xiàn)了 List 接口,具體框架圖如下:

【 說明 】
- ArrayList是以泛型方式實現(xiàn)的,使用時必須要先實例化
- ArrayList實現(xiàn)了RandomAccess接口,表明ArrayList支持隨機訪問
- ?ArrayList實現(xiàn)了Cloneable接口,表明ArrayList是可以clone的
- ArrayList實現(xiàn)了Serializable接口,表明ArrayList是支持序列化的
- 和Vector不同,ArrayList不是線程安全的,在單線程下可以使用,在多線程中可以選擇Vector或者 CopyOnWriteArrayList
- ArrayList底層是一段連續(xù)的空間,并且可以動態(tài)擴容,是一個動態(tài)類型的順序表
ArrayList 使用
ArrayList 的構造
方法 | 解釋 |
ArrayList() | 無參構造 |
ArrayList(Collection<? extends E> c) | 利用其他 Collection 構建 ArrayList |
ArrayList(int initialCapacity) | 指定順序表初始容量 |
public static void main(String[] args) {// ArrayList創(chuàng)建,推薦寫法// 構造一個空的列表List<Integer> list1 = new ArrayList<>();// 構造一個具有10個容量的列表List<Integer> list2 = new ArrayList<>(10);list2.add(1);list2.add(2);list2.add(3);// list2.add("hello"); // 編譯失敗,List<Integer>已經(jīng)限定了,list2中只能存儲整形元素// list3構造好之后,與list中的元素一致ArrayList<Integer> list3 = new ArrayList<>(list2);// 避免省略類型,否則:任意類型的元素都可以存放,使用時將是一場災難List list4 = new ArrayList();list4.add("111");list4.add(100);
}
ArrayList 常見操作
ArrayList 雖然提供的方法比較多,但是常用方法如下所示,需要用到其他方法時,可以自行查看 ArrayList 的幫助文檔
方法 | 解釋 |
boolean add(E e) | 尾插 e |
void add(int index, E element) | 將 e 插入到 index 位置 |
boolean addAll(Collection<? extends E> c) | 尾插 c 中的元素 |
E remove(int index) | 刪除 index 位置元素 |
boolean remove(Object o) | 刪除遇到的第一個 o |
E get(int index) | 獲取下標 index 位置元素 |
E set(int index, E element) | 將下標 index 位置元素設置為 element |
void clear() | 清空 |
boolean contains(Object o) | 判斷 o 是否在線性表中 |
int indexOf(Object o) | 返回第一個 o 所在下標 |
int lastIndexOf(Object o) | 返回最后一個 o 的下標 |
List<E> subList(int fromIndex, int toIndex) | 截取部分 list |
public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("JavaSE");list.add("JavaWeb");list.add("JavaEE");list.add("JVM");list.add("測試課程");System.out.println(list);// 獲取list中有效元素個數(shù)System.out.println(list.size());// 獲取和設置index位置上的元素,注意index必須介于[0, size)間System.out.println(list.get(1));list.set(1, "JavaWEB");System.out.println(list.get(1));// 在list的index位置插入指定元素,index及后續(xù)的元素統(tǒng)一往后搬移一個位置list.add(1, "Java數(shù)據(jù)結構");System.out.println(list);// 刪除指定元素,找到了就刪除,該元素之后的元素統(tǒng)一往前搬移一個位置list.remove("JVM");System.out.println(list);// 刪除list中index位置上的元素,注意index不要超過list中有效元素個數(shù),否則會拋出下標越界異常list.remove(list.size()-1);System.out.println(list);// 檢測list中是否包含指定元素,包含返回true,否則返回falseif(list.contains("測試課程")){list.add("測試課程");}// 查找指定元素第一次出現(xiàn)的位置:indexOf從前往后找,lastIndexOf從后往前找list.add("JavaSE");System.out.println(list.indexOf("JavaSE"));System.out.println(list.lastIndexOf("JavaSE"));// 使用list中[0, 4)之間的元素構成一個新的SubList返回,但是和ArrayList共用一個elementData數(shù)組List<String> ret = list.subList(0, 4);System.out.println(ret);list.clear();System.out.println(list.size());
}
ArrayList的遍歷
ArrayList 可以使用三方方式遍歷: for 循環(huán) + 下標、 foreach 、使用迭代器
public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);// 使用下標+for遍歷for (int i = 0; i < list.size(); i++) {System.out.print(list.get(i) + " ");}System.out.println();// 借助foreach遍歷for (Integer integer : list) {System.out.print(integer + " ");}System.out.println();Iterator<Integer> it = list.listIterator();while(it.hasNext()){System.out.print(it.next() + " ");}System.out.println();
}
ArrayList 的擴容機制
ArrayList 是一個動態(tài)類型的順序表,即:在插入元素的過程中會自動擴容。以下是 ArrayList 中擴容方式:
- 檢測是否真正需要擴容,如果是調(diào)用grow準備擴容
- 預估需要庫容的大小
? ? ? ? 初步預估按照1.5倍大小擴容
? ? ? ? 如果用戶所需大小超過預估1.5倍大小,則按照用戶所需大小擴容
? ? ? ??真正擴容之前檢測是否能擴容成功,防止太大導致擴容失敗 - 使用copyOf進行擴容
ArrayList 的問題及思考
- ArrayList底層使用連續(xù)的空間,任意位置插入或刪除元素時,需要將該位置后序元素整體往前或者往后搬移,故時間復雜度為O(N)
- 增容需要申請新空間,拷貝數(shù)據(jù),釋放舊空間。會有不小的消耗。
- 增容一般是呈2倍的增長,勢必會有一定的空間浪費。例如當前容量為100,滿了以后增容到200,我們再繼續(xù)插入了5個數(shù)據(jù),后面沒有數(shù)據(jù)插入了,那么就浪費了95個數(shù)據(jù)空間
ArrayList的缺陷
由于ArrayList是通過數(shù)組來實現(xiàn)的其底層是一段連續(xù)空間,當 在 ArrayList 任意位置插入或者刪除元素時,就需要將后序元素整體往前或者往后 搬移,時間復雜度為 O(n) ,效率比較低,因此 ArrayList 不適合做任意位置插入和刪除比較多的場景 。因此: java 集合中又引入了LinkedList ,即鏈表結構。
鏈表的概念及結構
鏈表是一種 物理存儲結構上非連續(xù) 存儲結構,數(shù)據(jù)元素的 邏輯順序 是通過鏈表中的 引用鏈接 次序?qū)崿F(xiàn)的 。

LinkedList
LinkedList 的底層是雙向鏈表結構 ,由于鏈表沒有將元素存儲在連續(xù)的空間中,元素存儲在單獨的節(jié)點中,然后通過引用將節(jié)點連接起來了,因此在在任意位置插入或者刪除元素時,不需要搬移元素,效率比較高。

在集合框架中, LinkedList 也實現(xiàn)了 List 接口,具體如下:

【說明】
- LinkedList實現(xiàn)了List接口
- LinkedList的底層使用了雙向鏈表
- LinkedList沒有實現(xiàn)RandomAccess接口,因此LinkedList不支持隨機訪問
- LinkedList的任意位置插入和刪除元素時效率比較高,時間復雜度為O(1)
- LinkedList比較適合任意位置插入的場景
LinkedList 的使用
方法 | 解釋 |
LinkedList() | 無參構造 |
public LinkedList(Collection<? extends E> c) | 使用其他集合容器中元素構造List |
public static void main(String[] args) {// 構造一個空的LinkedListList<Integer> list1 = new LinkedList<>();List<String> list2 = new java.util.ArrayList<>();list2.add("JavaSE");list2.add("JavaWeb");list2.add("JavaEE");// 使用ArrayList構造LinkedListList<String> list3 = new LinkedList<>(list2);
}
LinkedList 的其他常用方法介紹
方法 | 解釋 |
boolean add(E e) | 尾插 e |
void add(int index, E element) | 將 e 插入到 index 位置 |
boolean addAll(Collection<? extends E> c) | 尾插 c 中的元素 |
E remove(int index) | 刪除 index 位置元素 |
boolean remove(Object o) | 刪除遇到的第一個 o |
E get(int index) | 獲取下標 index 位置元素 |
E set(int index, E element) | 將下標 index 位置元素設置為 element |
void clear() | 清空 |
boolean contains(Object o) | 判斷 o 是否在線性表中 |
int indexOf(Object o) | 返回第一個 o 所在下標 |
int lastIndexOf(Object o) | 返回最后一個 o 的下標 |
List<E> subList(int fromIndex, int toIndex) | 截取部分 list |
public static void main(String[] args) {LinkedList<Integer> list = new LinkedList<>();list.add(1); // add(elem): 表示尾插list.add(2);list.add(3);list.add(4);list.add(5);list.add(6);list.add(7);System.out.println(list.size());System.out.println(list);// 在起始位置插入0list.add(0, 0); // add(index, elem): 在index位置插入元素elemSystem.out.println(list);list.remove(); // remove(): 刪除第一個元素,內(nèi)部調(diào)用的是removeFirst()list.removeFirst(); // removeFirst(): 刪除第一個元素list.removeLast(); // removeLast(): 刪除最后元素list.remove(1); // remove(index): 刪除index位置的元素System.out.println(list);// contains(elem): 檢測elem元素是否存在,如果存在返回true,否則返回falseif(!list.contains(1)){list.add(0, 1);}list.add(1);System.out.println(list);System.out.println(list.indexOf(1)); // indexOf(elem): 從前往后找到第一個elem的位置System.out.println(list.lastIndexOf(1)); // lastIndexOf(elem): 從后往前找第一個1的位置int elem = list.get(0); // get(index): 獲取指定位置元素list.set(0, 100); // set(index, elem): 將index位置的元素設置為elemSystem.out.println(list);// subList(from, to): 用list中[from, to)之間的元素構造一個新的LinkedList返回List<Integer> copy = list.subList(0, 3); System.out.println(list);System.out.println(copy);list.clear(); // 將list中元素清空System.out.println(list.size());
}
LinkedList 的遍歷
public static void main(String[] args) {LinkedList<Integer> list = new LinkedList<>();list.add(1); // add(elem): 表示尾插list.add(2);list.add(3);list.add(4);list.add(5);list.add(6);list.add(7);System.out.println(list.size());// foreach遍歷for (int e:list) {System.out.print(e + " ");}System.out.println();// 使用迭代器遍歷---正向遍歷ListIterator<Integer> it = list.listIterator();while(it.hasNext()){System.out.print(it.next()+ " ");}System.out.println();// 使用反向迭代器---反向遍歷ListIterator<Integer> rit = list.listIterator(list.size());while (rit.hasPrevious()){System.out.print(rit.previous() +" ");}System.out.println();
}
ArrayList 和 LinkedList 的區(qū)別
不同點 | ArrayList | LinkedList |
存儲空間上 | 物理上一定連續(xù) | 邏輯上連續(xù),但物理上不一定連續(xù) |
隨機訪問 | 支持O(1) | 不支持:O(N) |
頭插 | 需要搬移元素,效率低O(N) | 只需修改引用的指向,時間復雜度為O(1) |
插入 | 空間不夠時需要擴容 | 沒有容量的概念 |
應用場景 | 元素高效存儲+頻繁訪問 | 任意位置插入和刪除頻繁 |