list最大容量_Java 基礎(四)集合源碼解析 List

b642492d397415ab174c818e30231562.png

List 接口

前面我們學習了Iterator、Collection,為集合的學習打下了基礎,現在我們來學習集合的第一大體系 List。

List 是一個接口,定義了一組元素是有序的、可重復的集合。

6cd13ab4f71d8d06b9200d048dbf2f89.png

List 繼承自 Collection,較之 Collection,List 還添加了以下操作方法

  • 位置相關:List 的元素是有序的,因此有get(index)、set(index,object)、add(index,object)、remove(index) 方法。
  • 搜索:indexOf(),lastIndexOf();
  • 迭代:使用 Iterator 的功能板迭代器
  • 范圍性操作:使用 subList 方法對 list 進行任意范圍操作。

List的抽象實現類 AbstractList

AbstractList 繼承自 AbstractCollection 類,實現了 List 接口。整個類的設計類似于AbstractCollection,實現了大多數方法,抽象了對于需要根據數據操作的方法。

List 的實現類

ArrayList

ArrayList 是我們最常用的一個類,它具有如下特點:

  • 容量不固定,可以動態擴容
  • 有序(基于數組的實現,當然有序~~)
  • 元素可以為 null
  • 效率高查找操作的時間復雜度是 O(1)增刪操作的時間復雜度是 O(n)其他操作基本也都是 O(n)
  • 占用空間少,相比 LinkedList,不用占用額外空間維護表結構
28ffb3b960f47e2ed69ca91e1c251319.png

從成員變量,我們可以得知

  • Object[] elementData:數據結構---數組
  • 兩個默認空數組,僅在構造方法中使用,不關心
  • DEFAULT_CAPACITY: 數組初始容量為10
  • size:當前元素個數
  • MAX_ARRAY_SIZE:數組最大容量

現在我們知道了 ArrayList 其實就是基于數組的實現。因此,增刪改查操作就變得很容易理解了。

  • get(index)直接獲取數組的底 index 個元素
  • set(index,object)直接修改數組的第 index 個元素的引用
  • add(index,object)添加一個元素到index,這里會牽涉到數組的擴容,擴容我們后面再單獨看

這里的操作很簡單,比如說含有8個元素的數組array,要在第五個位置插入一個元素x,則將第[5,8)角標的元素分別往后移動一位變成[6,9),此時角標為5的位置空出來,使 array[5] = x 即可。

  • remove(object)刪除一個元素,刪除的過程同添加元素。

現在我們來看看擴容機制,假設我們現在有一個集合 list,里面正好含有10個元素,此時,我們調用 add(object)方法添加一個元素,看看是怎樣執行擴容操作的。

public boolean add(E var1) {    //查看是數組長度是否夠    this.ensureCapacityInternal(this.size + 1);    this.elementData[this.size++] = var1;    return true;}private void ensureCapacityInternal(int var1) {    //檢查是否是默認長度為0的數組,如果是則長度設為10    if(this.elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {        var1 = Math.max(10, var1);    }    this.ensureExplicitCapacity(var1);}private void ensureExplicitCapacity(int var1) {    ++this.modCount;    //當前需要的長度大于數組長度,執行擴容操作    if(var1 - this.elementData.length > 0) {        this.grow(var1);    }}private void grow(int var1) {    int var2 = this.elementData.length;    //var3 = var2*1.5;擴容1.5倍    int var3 = var2 + (var2 >> 1);    if(var3 - var1 < 0) {        var3 = var1;    }    //新容量超出最大值    if(var3 - 2147483639 > 0) {        var3 = hugeCapacity(var1);    }    //重新創建了一個1.5倍容量的數組賦值給elementData    this.elementData = Arrays.copyOf(this.elementData, var3);}復制代碼

從上面我們可以看到,修改某個角標的值或者查找某個角標的值時,我們可以直接調用數組的操作,效率很高。但是添加和刪除則是要操作整個數組的移動,效率稍低。

這里我們也可以看到,其實 ArrayList 就是一個針對數組操作的封裝類。

LinkedList

剛剛我們看了 ArrayList,ArrayList 的增刪操作效率相對較低。因此,Java 給我們設計了另外一種增刪效率比較高的集合 LinkedList。

ffccd72ee4e07ae068e425cfb673f69b.png

LinkedList 繼承自 AbstractSequentialList。

AbstractSequentialList 又繼承自AbstractList,并且基于 iterator 實現了默認增刪改查操作。

再回過頭來看 LinkedList,LinkedList 還實現了Deque(雙向隊列)接口,雙向隊列后面我們會單獨去學習,這里不再做過多的贅述。

再來看看成員變量~~

  • size 鏈表元素個數
  • first 第一個元素
  • last 最后一個元素

特點?和 ArrayList 的優缺點互補。

鏈表的實現,鏈表的實現很簡單,就是最基本的鏈表數據結構。理解鏈表數據結構可以跳過這里了。

我舉個例子吧,現在要讓 a、b、c、d 四個同學按順序投籃。有兩種方法,第一種是 abcd 排成一個隊伍,依次去投籃;但是體育課上讓所有的同學等著投籃很浪費時間,因此有了第二種辦法:依次告訴 a‘你投了藍之后叫 b 來投籃’,告訴 b‘你投了藍之后叫 c 來投籃’以此類推。這樣,就形成了一個簡單的單向列表,abcd 按照順序依次去投籃。此時,x 同學由于身體不舒服需要提前投籃回教室休息,則老師只需要告訴 a 同學投完籃之后不用叫 b 同學了,改叫 x 同學,x 同學投完籃之后叫 b 同學即可。不多說了,新手聽不懂,老手用不上。不懂鏈表的同學好好去學學數據結構吧。

后面的增刪改查操作就只是基礎的遍歷鏈表操作,就不去一一去讀源碼了,鏈表操作記不太清楚的同學可以去看一下 LinkedList 的源碼。

Vector

在學習了 ArrayList 之后,Vector 這個類我想用”線程安全的 ArrayList“可以一句話概括了。

Vector 和 ArrayList 一樣都繼承自 AbstractList,為什么說”Vector 是線程安全的 ArrayList“,本來還準備列個表讓大家對比一下成員變量以及主要操作方法的實現。but,除了 Vector 的方法上多了個 synchronized 外,代碼都是一樣的,比較個毛。因此,如果需要考慮線程安全,直接使用 Vector 即可,但是因為所有方法都加了synchronized ,效率相對會比較低,如果沒有線程安全的需求,那就使用 ArrayList 唄。

最后,還是說一下Vector 和 ArrayList的區別吧,反正也沒什么卵用,大家看看就好

  • Vector 出生早,JDK1.0的時候出生的,ArrayList 是1.2才出生
  • Vector 是線程安全的,ArrayList 不是。(這是最大的特點了)
  • Vector 默認擴容2倍,ArrayList 是1.5倍。這個~~有意義嗎?
  • Vector 多了一種迭代器 Enumeration。好吧,反正我沒用過。

Enumeration

為了找到 Enumeration 這種迭代器有什么特點,我去翻了一下 Vector 的代碼,找到了一個這樣的方法和這樣的接口,你們感受一下。

public Enumeration elements() {    return new Enumeration() {        int count = 0;        public boolean hasMoreElements() {            return this.count < Vector.this.elementCount;        }        public E nextElement() {            Vector var1 = Vector.this;            synchronized(Vector.this) {//區別在這里                if(this.count < Vector.this.elementCount) {                    return Vector.this.elementData(this.count++);                }            }            throw new NoSuchElementException("Vector Enumeration");        }    };}public interface Enumeration {    boolean hasMoreElements();    E nextElement();}復制代碼

mmp,這個 Enumeration 和Iterator 接口除了名字不一樣,還有什么區別?然后仔細看了一遍,在elements()方法里面的匿名內部了里面找到了nextElement()方法里面有個同步代碼塊。好吧, Enumeration 大概是線程安全的Iterator?

Stack

Stack 繼承自Vector,也是一個線程安全的集合。

Stack 也是基于數組實現的。

Stack 實現的是棧結構集合

什么是棧結構?

數據結構中,棧也是一種線性的數據結構,遵守 LIFO(后進先出)的操作順序,這里用一張很污的圖,保證你們看了之后能熟記棧結構特征。

小時候肯定都玩過羽毛球吧,羽毛球不經打,要經常換球,于是我買了一盒羽毛球,如下圖,就是一個羽毛球盒子,最先放進去的羽毛球(棧底的),要最后才能取出來。

format,png

Stack 的 代碼實現

類結構圖如下,代碼量也不多,一共才30幾行

cedb86581c3a6d63da6abec6962b5753.png
public class Stack extends Vector {    private static final long serialVersionUID = 1224463164541339165L;    public Stack() {    }    //入棧,添加一個元素到數組的最后一個    public E push(E var1) {        this.addElement(var1);        return var1;    }    //出棧,刪除數組最后一個元素并返回    public synchronized E pop() {        int var2 = this.size();        Object var1 = this.peek();        this.removeElementAt(var2 - 1);        return var1;    }    //獲取最后一個元素,不刪除    public synchronized E peek() {        int var1 = this.size();        if(var1 == 0) {            throw new EmptyStackException();        } else {            return this.elementAt(var1 - 1);        }    }    public boolean empty() {        return this.size() == 0;    }    獲取棧中的 位置。    public synchronized int search(Object var1) {        int var2 = this.lastIndexOf(var1);        return var2 >= 0?this.size() - var2:-1;    }}復制代碼

整個類的實現非常簡單,就是繼承 Vector,然后添加了 peek、pop、push、search 等方法,然后然添加刪除都在最末尾的元素做操作即可。

思考:怎樣用鏈表的結構快速實現 LinkedListStack?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/536967.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/536967.shtml
英文地址,請注明出處:http://en.pswp.cn/news/536967.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Mybatis源碼閱讀(四):核心接口4.1——StatementHandler

*************************************優雅的分割線 ********************************** 分享一波:程序員賺外快-必看的巔峰干貨 如果以上內容對你覺得有用,并想獲取更多的賺錢方式和免費的技術教程 請關注微信公眾號:HB荷包 一個能讓你學習技術和賺錢方法的公眾號,持續更…

Shell學習之結合正則表達式與通配符的使用(五)

Shell學習之結合正則表達式與通配符的使用 目錄 通配符 正則表達式與通配符通配符通配符的使用正則表達式 正則表達式正則表達式的使用通配符 正則表達式與通配符 正則表達式用來在文件中匹配符合條件的字符串&#xff0c;正則是包含匹配。grep、awk、sed等命令可以支持正則表達…

Mybatis源碼閱讀(四):核心接口4.2——Executor(上)

*************************************優雅的分割線 ********************************** 分享一波:程序員賺外快-必看的巔峰干貨 如果以上內容對你覺得有用,并想獲取更多的賺錢方式和免費的技術教程 請關注微信公眾號:HB荷包 一個能讓你學習技術和賺錢方法的公眾號,持續更…

接收xml參數_SpringBoot實戰(二):接收xml請求

強烈推薦一個大神的人工智能的教程&#xff1a;http://www.captainbed.net/zhanghan【前言】最近在對接一個第三方系統&#xff0c;需要接收第三方系統的回調&#xff0c;而且格式為XML形式&#xff0c;之前自己一般接收的參數是Json形式&#xff0c;于是乎做個實驗驗證一下使用…

報錯 插入更新_window如何解決mysql數據量過大導致的報錯

window如何解決報錯“The total number of locks exceeds the lock table size”第一大步&#xff0c;查看mysql配置信息在CMD中輸入mysql -hlocalhost -uroot -p #如果設置了密碼直接接在p 后面 show variables like %storage_engine%以下為結果可以看到InnoDB是MySQL的默認引…

148. Sort List

Sort a linked list in O(n log n) time using constant space complexity. Example 1: Input: 4->2->1->3 Output: 1->2->3->4 Example 2: Input: -1->5->3->4->0 Output: -1->0->3->4->5難度&#xff1a;medium 題目&#xff1a;排…

Mybatis源碼閱讀(四):核心接口4.2——Executor(下)

*************************************優雅的分割線 ********************************** 分享一波:程序員賺外快-必看的巔峰干貨 如果以上內容對你覺得有用,并想獲取更多的賺錢方式和免費的技術教程 請關注微信公眾號:HB荷包 一個能讓你學習技術和賺錢方法的公眾號,持續更…

python解橢圓方程的例題_橢圓標準方程典型例題及練習題

橢圓標準方程典型例題例1已知P 點在以坐標軸為對稱軸的橢圓上&#xff0c;點P 到兩焦點的距離分別為354和352&#xff0c;過P 點作焦點所在軸的垂線&#xff0c;它恰好過橢圓的一個焦點&#xff0c;求橢圓方程&#xff0e; 解&#xff1a;設兩焦點為1F 、2F &#xff0c;且3541…

leetcode393. UTF-8 Validation

題目要求 A character in UTF8 can be from 1 to 4 bytes long, subjected to the following rules:For 1-byte character, the first bit is a 0, followed by its unicode code. For n-bytes character, the first n-bits are all ones, the n1 bit is 0, followed by n-1 by…

Mybatis源碼閱讀(五 ):接口層——SqlSession

*************************************優雅的分割線 ********************************** 分享一波:程序員賺外快-必看的巔峰干貨 如果以上內容對你覺得有用,并想獲取更多的賺錢方式和免費的技術教程 請關注微信公眾號:HB荷包 一個能讓你學習技術和賺錢方法的公眾號,持續更…

插入公式_一個小工具,徹底幫你搞定在Markdown中插入公式的問題

在編輯Markdown文檔時&#xff0c;插入公式是一個挺麻煩的活兒。需要掌握LaTex語法。我自己看完語法后&#xff0c;直接放棄&#xff0c;這絕對是反人類的語法。&#xff08;好吧&#xff0c;是我不會用...&#xff09;但是&#xff0c;我相信你看了這篇文章后&#xff0c;絕對…

JavaScript數據結構與算法——字典

1.字典數據結構 在字典中&#xff0c;存儲的是【鍵&#xff0c;值】對&#xff0c;其中鍵名是用來查詢特定元素的。字典和集合很相似&#xff0c;集合以【值&#xff0c;值】的形式存儲&#xff0c;字典則是用【鍵&#xff0c;值】對的形式存儲。字典也稱作映射。 2.創建字典 f…

Mybatis源碼閱讀(一):Mybatis初始化1.2 —— 解析別名、插件、對象工廠、反射工具箱、環境

*************************************優雅的分割線 ********************************** 分享一波:程序員賺外快-必看的巔峰干貨 如果以上內容對你覺得有用,并想獲取更多的賺錢方式和免費的技術教程 請關注微信公眾號:HB荷包 一個能讓你學習技術和賺錢方法的公眾號,持續更…

中西方對時間的差異_中西方時間觀念差異 英文

The concept of time(時間觀念)①Inchina&#xff0c;words and phrases about time are very general. Forexample&#xff0c;ifyoudatewithsomeone,mostofChineseusedtoanswer: in the afternoon /at night/after a while and so on.Butinwestern,peoplehaveaverystrongconc…

Google 修改 Chrome API,防止隱身模式檢測

開發四年只會寫業務代碼&#xff0c;分布式高并發都不會還做程序員&#xff1f; 在使用 Chrome 瀏覽網頁時&#xff0c;某些網站會使用某種方法來確定訪問者是否處于隱身模式&#xff0c;這是一種隱私泄漏行為。Google 目前正在考慮修改 Chrome 的相關 API&#xff0c;來杜絕…

Mybatis源碼閱讀(一):Mybatis初始化1.1 解析properties、settings

*************************************優雅的分割線 ********************************** 分享一波:程序員賺外快-必看的巔峰干貨 如果以上內容對你覺得有用,并想獲取更多的賺錢方式和免費的技術教程 請關注微信公眾號:HB荷包 一個能讓你學習技術和賺錢方法的公眾號,持續更…

亞馬遜推薦python_使用python查找amazon類別

我想得到amazon的類別&#xff0c;我計劃廢棄不用API。我已經取消了http://www.amazon.com&#xff0c;我已經在Shop By Department下拉列表中抓取了所有的類別和子類別&#xff0c;我創建了一個web服務來完成這項工作&#xff0c;代碼就在這里route(/hello)def hello():textli…

JavaScript異步基礎

唯一比不知道代碼為什么崩潰更可怕的事情是&#xff0c;不知道為什么一開始它是工作的&#xff01;在 ECMA 規范的最近幾次版本里不斷有新成員加入&#xff0c;尤其在處理異步的問題上&#xff0c;更是不斷推陳出新。然而&#xff0c;我們在享受便利的同時&#xff0c;也應該了…

Flutter、ReactNative、uniapp對比

*************************************優雅的分割線 ********************************** 分享一波:程序員賺外快-必看的巔峰干貨 如果以上內容對你覺得有用,并想獲取更多的賺錢方式和免費的技術教程 請關注微信公眾號:HB荷包 一個能讓你學習技術和賺錢方法的公眾號,持續更…

JavaScript數組方法

一、基本類型和引用類型 數值、字符串、布爾值、undefined、null可以直接寫出來&#xff0c;比較簡單的數據稱為基本類型&#xff0c;在比較的時候&#xff0c;是直接按值比較。對象、函數、數組復雜的數據是引用類型&#xff0c;在比較的時候&#xff0c;是按照地址比較。cons…