java簡單數據結構_圖解Java常用數據結構

最近在整理數據結構方面的知識, 系統化看了下 Java 中常用數據結構, 突發奇想用動畫來繪制數據流轉過程.

主要基于 jdk8, 可能會有些特性與 jdk7 之前不相同, 例如 LinkedList LinkedHashMap 中的雙向列表不再是回環的.

HashMap 中的單鏈表是尾插, 而不是頭插入等等, 后文不再贅敘這些差異, 本文目錄結構如下:

e609f304d56fdaae5e2446ad2ffd48e5.png

LinkedList

經典的雙鏈表結構, 適用于亂序插入, 刪除. 指定序列操作則性能不如 ArrayList, 這也是其數據結構決定的.

add(E) / addLast(E)

1f2a22b400b1a7183eebccf6fa4e8f19.gif

add(index, E)

這邊有個小的優化, 他會先判斷 index 是靠近隊頭還是隊尾, 來確定從哪個方向遍歷鏈入.

if(index>1))

Node?x = first;

for (inti = 0; i < index; i++) {

x = x.next;

}

return x;

}else{

Node?x = last;

for (int i = size - 1; i > index; i--) {

x = x.prev;

}

return x;

}

3a67a82a7dc1fa1369f7eef6967cd479.gif

靠隊尾

207d2225b3932ba30c5fc102ca6bc50a.gif

get(index)

也是會先判斷 index, 不過性能依然不好, 這也是為什么不推薦用 for(int i = 0; i < lengh; i++) 的方式遍歷 linkedlist, 而是使用 iterator 的方式遍歷.

e7d575d91f00c73e16329f950eb8163f.gif

ee72b65619efb40c3f9f8d20c156bab2.gif

remove(E)

ArrayList

底層就是一個數組, 因此按序查找快, 亂序插入, 刪除因為涉及到后面元素移位所以性能慢.

add(index, E)

e501a0c897f7e7af220690069019f6c4.gif

擴容

一般默認容量是 10, 擴容后, 會 length*1.5.

ed271411ee797f5d554fd0e6c9689d67.gif

remove(E)

循環遍歷數組, 判斷 E 是否 equals 當前元素, 刪除性能不如 LinkedList.

87f8c893bfaf2adeb1f1bedf1301b86c.gif

Stack

經典的數據結構, 底層也是數組, 繼承自 Vector, 先進后出 FILO, 默認 new Stack() 容量為 10, 超出自動擴容.

push(E)

c6f0fc0f80c0a7226da2045ba55369df.gif

pop()

0671208ec1b56ab4cfca211a0fd52137.gif

后綴表達式

Stack 的一個典型應用就是計算表達式如 9 + (3 - 1) * 3 + 10 / 2, 計算機將中綴表達式轉為后綴表達式, 再對后綴表達式進行計算.

中綴轉后綴

數字直接輸出

棧為空時,遇到運算符,直接入棧

遇到左括號, 將其入棧

遇到右括號, 執行出棧操作,并將出棧的元素輸出,直到彈出棧的是左括號,左括號不輸出。

遇到運算符 (加減乘除):彈出所有優先級大于或者等于該運算符的棧頂元素,然后將該運算符入棧

最終將棧中的元素依次出棧,輸出。

c39ccaf7118bbc2226bca1a1eabf3edc.gif

計算后綴表達

遇到數字時,將數字壓入堆棧

遇到運算符時,彈出棧頂的兩個數,用運算符對它們做相應的計算, 并將結果入棧

重復上述過程直到表達式最右端

運算得出的值即為表達式的結果

0ec07653a182e6195f2d8c158286a289.gif

隊列

與 Stack 的區別在于, Stack 的刪除與添加都在隊尾進行, 而 Queue 刪除在隊頭, 添加在隊尾.

ArrayBlockingQueue

生產消費者中常用的阻塞有界隊列, FIFO.

put(E)

4e4926ec5c22a596a8a7e99289a6dc2d.gif

put(E) 隊列滿了

final ReentrantLocklock=this.lock;

lock.lockInterruptibly();

try{

while(count == items.length)

notFull.await();

enqueue(e);

}finally{

lock.unlock();

}

take()

當元素被取出后, 并沒有對數組后面的元素位移, 而是更新 takeIndex 來指向下一個元素.

takeIndex 是一個環形的增長, 當移動到隊列尾部時, 會指向 0, 再次循環.

private E dequeue() {

// assert lock.getHoldCount() == 1;

// assert items[takeIndex] != null;

final Object[] items = this.items;

@SuppressWarnings("unchecked")

E x = (E) items[takeIndex];

items[takeIndex] = null;

if (++takeIndex == items.length){

takeIndex = 0;

}

count--;

if (itrs != null){

itrs.elementDequeued();

}

notFull.signal();

return x;

}

18ca4cf0fb2e9ffd1f200686a99a16b7.gif

HashMap

最常用的哈希表, 面試的童鞋必備知識了, 內部通過數組 + 單鏈表的方式實現. jdk8 中引入了紅黑樹對長度 > 8 的鏈表進行優化, 我們另外篇幅再講.

put(K, V****)

ec99ca5cfe0a59eeb710811c84e559dd.gif

put(K, V) 相同 hash 值

322720a08c0d803f6a479a9dedeb45a1.gif

resize 動態擴容

當 map 中元素超出設定的閾值后, 會進行 resize (length * 2) 操作, 擴容過程中對元素一通操作, 并放置到新的位置.

具體操作如下:

在 jdk7 中對所有元素直接 rehash, 并放到新的位置.

在 jdk8 中判斷元素原 hash 值新增的 bit 位是 0 還是 1, 0 則索引不變, 1 則索引變成 "原索引 + oldTable.length".

// 定義兩條鏈

// 原來的 hash 值新增的 bit 為 0 的鏈,頭部和尾部

Node?loHead =null, loTail =null;

// 原來的 hash 值新增的 bit 為 1 的鏈,頭部和尾部

Node?hiHead =null, hiTail =null;

Node?next;

// 循環遍歷出鏈條鏈

do{

next = e.next;

if((e.hash & oldCap) ==0) {

if(loTail ==null){

loHead = e;

}else{

loTail.next = e;

}

loTail = e;

}else{

if(hiTail ==null){

hiHead = e;

}else{

hiTail.next = e;

}

hiTail = e;

}

}while((e = next) !=null);

// 擴容前后位置不變的鏈

if(loTail !=null) {

loTail.next =null;

newTab[j] = loHead;

}

// 擴容后位置加上原數組長度的鏈

if(hiTail !=null) {

hiTail.next =null;

newTab[j + oldCap] = hiHead;

}

707bc76901bab3cb24d837b01fa3bd67.gif

LinkedHashMap

繼承自 HashMap, 底層額外維護了一個雙向鏈表來維持數據有序. 可以通過設置 accessOrder 來實現 FIFO(插入有序) 或者 LRU(訪問有序) 緩存.

put(K, V)

515cad9713c53f700a7b6b8ad60624b9.gif

get(K)

accessOrder 為 false 的時候, 直接返回元素就行了, 不需要調整位置.

accessOrder 為 true 的時候, 需要將最近訪問的元素, 放置到隊尾.

removeEldestEntry 刪除最老的元素

dfd7051f26c343189b00eb73e51942a3.gif

**?為了讓學習變得輕松、高效,今天給大家免費分享一套 Java 教學資源。幫助大家在成為 Java 架構師的道路上披荊斬棘。需要資料的歡迎關注微信公眾號:Java知己**

“不積跬步,無以至千里”,希望未來的你能:有夢為馬 隨處可棲!加油,少年!

關注公眾號:「Java 知己」,每天更新Java知識哦,期待你的到來!

發送「Group」,與 10 萬程序員一起進步。

發送「面試」,領取BATJ面試資料、面試視頻攻略。

發送「玩轉算法」,領取《玩轉算法》系列視頻教程。

千萬不要發送「1024」...

dc729105dd03485df452d4db005bf16b.png

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

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

相關文章

jest java_?使用jest進行測試驅動開發

前言本文將使用jest進行測試驅動開發的示例&#xff0c;源碼在github。重點說明在開發中引入單元測試后開發過程&#xff0c;以及測試先行的開發思路。本文的重點是過程以及思維方法&#xff0c;框架以及用法不是重點。本文使用的編程語言是javascript&#xff0c;思路對其他語…

mysql sqlstate 08001_關于Toad連接DB2的sqlstate=08001錯誤

新裝的centos6.3db29.7&#xff0c;數據庫導入完了的之后用Toad連接訪問之的時候出錯了。DB2 Database Error: ERROR [08001] [IBM] SQL30081N A communication error has been detected. Communication protocol being used: "TCP/IP". Communication API being use…

mysql 設置主鍵命令_MySQL常用命令

1、修改MySQL密碼方法一&#xff1a;use mysql&#xff1b;update user set passwordPASSWORD(“123456”) where user‘root’&#xff1b;flush privileges&#xff1b;忘記密碼&#xff1a;sed -ri 3d skip-grant-tables /etc/my.cnfsystemctl restart mariadbuse mysql&…

python 整除的數組_計算和可被整除的所有子數組

在我學習面試的時候&#xff0c;我在GeeksForGeeks上找到了這個問題和解決方案&#xff0c;但不明白答案。在上面說的是Let there be a subarray (i, j) whose sum is divisible by ksum(i, j) sum(0, j) - sum(0, i-1)Sum for any subarray can be written as q*k rem where…

java ha_java – Haproxy Bad Gateway 502

所以我在Jetty servlet面前使用HAProxy.目前的目標只是在配置完所有內容后進行概念驗證,加載和壓力測試.但是我在配置haproxy時遇到問題.我知道這不是我的應用程序的問題,因為我有運行nginx(tengine),一切正常.所以它必須與haproxy配置或haproxy工作的方式不適合我的需要.所以我…

java ioutils_java – 無法解析符號’IOUtils’

我使用以下代碼在我的Android應用程序中創建一個臨時文件&#xff1a;public File streamToFile (InputStream in) throws IOException {File tempFile File.createTempFile("sample", ".tmp");tempFile.deleteOnExit();FileOutputStream out new FileOu…

java const關鍵字_const關鍵字:終于擁有真正的常量聲明語句

你好&#xff0c;今天大叔想和你嘮扯嘮扯 ES6 新增的關鍵字 —— const。在說 const 關鍵字之前&#xff0c;大叔先和你嘮嘮大叔自己對 const 的感受 —— JavaScript 尼瑪終于可以聲明真正的常量啦&#xff01;大叔為啥會發出這樣滴感嘆&#xff1f;實在是“天下苦秦久矣”呀~…

workerman高并發異步mysql_workerman怎么實現高并發

并發概念太模糊&#xff0c;這里以兩種可以量化的指標并發連接數和并發請求數來說明。并發連接數是指服務器當前時刻一共維持了多少TCP連接&#xff0c;而這些連接上是否有數據通訊并不關注。 (推薦學習&#xff1a; workerman教程)例如一臺消息推送服務器上可能維持了百萬的設…

checkout 撤銷修改_Git的4個階段的撤銷更改

雖然git誕生距今已有12年之久&#xff0c;網上各種關于git的介紹文章數不勝數&#xff0c;但是依然有很多人(包括我自己在內)對于它的功能不能完全掌握。以下的介紹只是基于我個人對于git的理解&#xff0c;并且可能生編硬造了一些不完全符合git說法的詞語。目的只是為了讓git通…

移除Java對象中的屬性_在java對象中添加和刪除屬性

我怎樣才能在 java中實現這一點.我有一個具有屬性的對象.public class Object {private final Credentials Credentials;private final int PageSize;private final int PageStart;private final int DefaultFilterId;public Object(Credentials Credentials, int PageSize, in…

java軟件開發ea介紹_開發說明 — Eacloud 1.0 documentation

PHP 代碼示例( Linux 版)解壓后&#xff0c;參考 phplinux/v3.4.0.1/文檔/PHP版服務器端工具包(Linux版)軟件使用手冊.pdfDemo 運行1.安裝對應版本的 PHP2.安裝運行時環境(glibc 庫等)3.修改 PHP 的配置文件 php.ini修改 php.ini&#xff0c;使 php 允許加載擴展&#xff0c;并…

java中operationBox_Java使用PDFBox開發包實現對PDF文檔內容編輯與保存

pdfbox開發包下載地址&#xff1a;http://pdfbox.apache.org/程序實現了PDF文檔的創建&#xff0c;讀入&#xff0c;與修改PDF內容并保存。可能有個前提&#xff0c;PDF文檔不是加密的&#xff0c;如果加密怎么辦&#xff0c;我沒研究過&#xff01;源代碼如下&#xff1a;pack…

java訪問權限最高_java 訪問權限

Java語言中的訪問權限修飾符有4種&#xff0c;但是僅有3個關鍵字&#xff0c;因為不寫訪問權限&#xff0c;在Java中被稱為默認權限&#xff0c;或同包權限&#xff0c;本文中以(default)代替。下面按照權限從小到大的順序對4中訪問權限分別介紹。class我個人&#xff0c;我有很…

java中 queryparam_java – 何時使用@QueryParam和@PathParam

我不是問這里已經問過的問題&#xff1a;What is the difference between PathParam and QueryParam這是一個“最佳實踐”或常規問題。什么時候使用PathParam和QueryParam。我可以想到的是&#xff0c;決定可能使用兩者來區分信息模式。讓我在下面說明我的LTPO – 不完美的觀察…

java中fork函數_java中的forkjoin框架的使用

fork join框架是java 7中引入框架&#xff0c;這個框架的引入主要是為了提升并行計算的能力。fork join主要有兩個步驟&#xff0c;第一就是fork&#xff0c;將一個大任務分成很多個小任務&#xff0c;第二就是join&#xff0c;將第一個任務的結果join起來&#xff0c;生成最后…

Java h264起始碼_h.264 – 使用H264視頻的起始碼

有兩種H.264流格式,有時也稱為>附件B(在原始H.264流中找到)> AVCC(在像MP4這樣的容器中找到)H.264流由NAL(包裝單位)組成(1)附件B&#xff1a;在每個NAL單元的字節[x00] [x00] [x00] [x01]之前有4字節的起始碼.[start code]--[NAL]--[start code]--[NAL] etc(2)AVCC&…

java中已定義類型car_Java 8 習慣用語(8):Java 知道您的類型

Java?8是第一個支持類型推斷的 Java 版本&#xff0c;而且它僅對 lambda 表達式支持此功能。在 lambda表達式中使用類型推斷具有強大的作用&#xff0c;它將幫助您做好準備以應對未來的 Java版本&#xff0c;在今后的版本中還會將類型推斷用于變量等更多可能。這里的訣竅在于恰…

ATM柜員機JAVA課程設計_ATM柜員機學年論文設計(Java課程設計)

內容簡介&#xff1a;ATM柜員機學年論文設計(Java課程設計)&#xff0c;共23頁&#xff0c;4599字&#xff0c;附源程序。一&#xff0e; 程序介紹3二&#xff0e; 開發環境搭建31. MyEclipse 5.5.1 GA安裝32. MyEclipse Designer 圖形設計插件安裝33. MySQL數據庫安裝4三&…

mysql 結果集什么意思_結果集中的mysql“和”邏輯

假設我有一個類似以下的數據集&#xff1a;table fooid | employeeType | employeeID-------------------------1 | Developer | 12 | Developer | 23 | Developer | 34 | Manager | 15 | Manager | 46 | Manager | 57 | CEO | 18 | CEO | 6我想運行一個查詢,該查詢將返回所有e…

opencv java 去干擾_java - OpenCV Java修補圖像格式要求 - 堆棧內存溢出

一直試圖讓修復工作在Android上進行&#xff0c;int height (int) viewMat.size().height;int width (int) viewMat.size().width;Mat maskMat new Mat();maskMat.create(viewMat.size(), CvType.CV_8U);maskMat.setTo(bColor);Point r1 new Point(width/2-width/10, heigh…