網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
在 Java 的核心庫(kù)中,集合框架可謂鼎鼎大名:Array
、List
、Set
、Queue
、HashMap
等等,隨便拎一個(gè)出來(lái)都值得開(kāi)發(fā)者好好學(xué)習(xí)如何使用甚至是背后的設(shè)計(jì)源碼(這類文章也挺多,大家上網(wǎng)隨便一搜)。
雖然 Go 語(yǔ)言沒(méi)有如此豐富的容器類型,但也有一些基本的容器供開(kāi)發(fā)者使用,接下來(lái)讓我們一一認(rèn)識(shí)這些容器類型吧。
序列容器
序列容器存儲(chǔ)特定類型的數(shù)據(jù)元素。目前有 5 種序列容器的實(shí)現(xiàn):
array
vector
deque
list
forward_list
這些序列容易可以用順序的方式保存數(shù)據(jù),利用這些序列容易能夠編寫(xiě)有效的代碼,重復(fù)使用標(biāo)準(zhǔn)庫(kù)的模塊化。
數(shù)組
Go 語(yǔ)言中的數(shù)組類型有點(diǎn)類似 C++ 中的數(shù)據(jù),Go 的數(shù)組初始化定義后,在編譯時(shí)就不會(huì)再變更。
定義數(shù)組的方式如下:
var a [10]int b := [5]string {"H", "e", "l", "l", "o"}
[n]T
類型就表示含有 n
個(gè)類型為 T
的數(shù)組,本例中就是 a 變量表示含有 10 個(gè) int 類型的整型數(shù)組;b 變量表示含有 5 個(gè) string 類型的字符串?dāng)?shù)組。 數(shù)組的長(zhǎng)度作為其類型的一部分,因此數(shù)組的長(zhǎng)度是無(wú)法調(diào)整的。
package main import "fmt" func main() { var a [10]int a[0] = 2022 a[1] = 2023 fmt.Println(a[0], a[1]) fmt.Println(a) b := [5]string {"H", "e", "l", "l", "o"} fmt.Println(b) }
運(yùn)行結(jié)果如下:
Vector
你可能會(huì)好奇,Go 語(yǔ)言又沒(méi)有 C++ 中的 Vector 類型,為什么會(huì)舉出這個(gè)例子。
其實(shí) Go 最初有一個(gè) Vector 類型的實(shí)現(xiàn),但在 2011 年 10 月 11 日,在 Go 語(yǔ)言的開(kāi)發(fā)階段被刪除了。保留了現(xiàn)在的切片,而切片就變成了實(shí)際上更好的 Vector 實(shí)現(xiàn)。
一個(gè)數(shù)組有固定的大小,但切片是一個(gè)動(dòng)態(tài)、靈活的數(shù)組元素的視圖,在實(shí)際中,切片比數(shù)組更為常見(jiàn)。
[]T
表示是一個(gè)具有類型 T
的元素切片,[]byte
?是 byte slice,指元素為 byte 的 slice;[]string
?是 string slice,指元素為 string 的 slice。
切片通過(guò)指定兩個(gè)切點(diǎn) a[low : high]
,可以定義如下的 sliceExample
切片:
sliceExample := []string{"Say", "Hello", "to", "you"}
切片對(duì)比數(shù)組的最大優(yōu)點(diǎn)就是:可以隨著增加和刪除來(lái)增加或減少容器的大小。我們來(lái)看一個(gè)例子:
package main import "fmt" // remove i indexed item in a slice func remove(s []string, i int) []string { copy(s[i:], s[i+1:]) return s[:len(s)-1] } func main() { primes := [6]int{2, 3, 5, 7, 11, 13} var s []int = primes[1:4] fmt.Println(s) sliceExample := []string{"Say", "Hello", "to", "you"} sliceExample = append(sliceExample, ",My Gopher Friends~") fmt.Println("Append Slice: ", sliceExample) sliceExample = remove(sliceExample, 0) fmt.Println("After Removed Item: ", sliceExample) }
運(yùn)行結(jié)果如下圖:
我們分享了 Go 語(yǔ)言提供的容器中的數(shù)組和切片,不管是數(shù)據(jù)還是切片,它們內(nèi)部的數(shù)據(jù)類型必須是一致的(要么都是整型、要么都是字符串類型)。但數(shù)據(jù)的大小是固定,而切片可以根據(jù)元素的添加和減少動(dòng)態(tài)調(diào)整容器大小。
Deque
Deque,即雙端隊(duì)列,是一個(gè)可以擴(kuò)展的容器。擴(kuò)展可以發(fā)生在容器的前面或后面。當(dāng)隊(duì)列的頂部或尾部需要經(jīng)常被引用時(shí),經(jīng)常使用雙端隊(duì)列。
Go 官網(wǎng)有一個(gè)雙端隊(duì)列的實(shí)現(xiàn),官方地址點(diǎn)此處。
下面的代碼塊顯示了 Go 雙端隊(duì)列 deque 的使用:
package main import ( "fmt" "github.com/gammazero/deque" ) func main() { var q deque.Deque[string] q.PushBack("I") q.PushBack("love") q.PushBack("learning") q.PushBack("Go") fmt.Println("隊(duì)列長(zhǎng)度為: ", q.Len()) // Prints: 4 fmt.Println("隊(duì)首為元素:", q.Front()) // Prints: I fmt.Println("隊(duì)尾為元素: ", q.Back()) // Prints: Go q.PopFront() // remove "I" q.PopBack() // remove "Go" q.PushFront("Hello") q.PushBack("World") // Consume deque and print elements. for q.Len() != 0 { fmt.Println(q.PopFront()) } }
運(yùn)行結(jié)果如圖:
List
List 在 Go 語(yǔ)言中有一個(gè)雙鏈表的實(shí)現(xiàn),它位于內(nèi)置標(biāo)準(zhǔn)庫(kù) container/list
包中,官網(wǎng)地址為:https://pkg.go.dev/container/list
我們可以直接使用這個(gè)鏈表的實(shí)現(xiàn):
package main import ( "container/list" "fmt" ) func main() { // Create a new list and put some numbers in it. l1 := list.New() e4 := l1.PushBack(4) e1 := l1.PushFront(1) l1.InsertBefore(3, e4) l1.InsertAfter(2, e1) // now l1 is [1 2 3 4] // Iterate through list and print its contents. for e := l1.Front(); e != nil; e = e.Next() { fmt.Println(e.Value) } l1.MoveToBack(e1) // now l1 is [4 2 3 1] listLength := l1.Len() // length is 4 fmt.Printf("l1 type: %T\n", l1) fmt.Println("l1 length : :", listLength) for e := l1.Front(); e != nil; e = e.Next() { fmt.Println(e.Value) } }
運(yùn)行結(jié)果為:
1
2
3
4
l1 type: *list.List
l1 length : : 4
2
3
4
1
單鏈表
最后介紹一下單鏈表,如果我們想實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)并沒(méi)有標(biāo)準(zhǔn)的容器集成,此時(shí)我們就可以通過(guò)自己根據(jù)要求來(lái)寫(xiě)一個(gè)自己想要的容器類型,這里以頭插法的單鏈表舉例:
package main import "fmt" type SinglyLinkedList struct { head *LinkedListNode } type LinkedListNode struct { data string next *LinkedListNode } func (ll *SinglyLinkedList) Append(node *LinkedListNode) { if ll.head == nil { ll.head = node return } currentNode := ll.head for currentNode.next != nil { currentNode = currentNode.next } currentNode.next = node } func main() { ll := &SinglyLinkedList{} ll.Append(&LinkedListNode{data: "Hello"}) ll.Append(&LinkedListNode{data: "Gopher"}) for e := ll.head; e != nil; e = e.next { fmt.Println(e.data) } }
運(yùn)行結(jié)果如圖:
當(dāng)然,還有更多的容器方法可以等著自己去擴(kuò)充,這一部分讀者感興趣可以在算法和數(shù)據(jù)結(jié)構(gòu)的知識(shí)點(diǎn)中進(jìn)行學(xué)習(xí)。
總結(jié)
本文介紹了 Go 語(yǔ)言的數(shù)組和切片類型,接著介紹了 Go 標(biāo)準(zhǔn)包 container
中的 list,最后實(shí)現(xiàn)了一個(gè)頭插法的單鏈表。如果在日常開(kāi)發(fā)過(guò)程中,有什么容器需要使用,可以從 pkg.go.dev/ 進(jìn)行搜索,會(huì)有很多開(kāi)源的 Go 優(yōu)秀開(kāi)源包,無(wú)論是學(xué)習(xí)還是使用,都能收獲滿滿。
原文鏈接:https://juejin.cn/post/7159483166695096334
相關(guān)推薦
- 2022-05-25 yarn : 無(wú)法加載文件
- 2022-07-15 python中的字符串占位符的"{0:2}"_python
- 2022-08-04 Python中reduce函數(shù)詳解_python
- 2022-07-12 Android Studio與夜神模擬器進(jìn)行連接以及連接中出現(xiàn)的問(wèn)題
- 2022-12-27 Python實(shí)現(xiàn)ATM簡(jiǎn)單功能的示例詳解_python
- 2022-06-28 C語(yǔ)言簡(jiǎn)明講解預(yù)編譯的使用_C 語(yǔ)言
- 2023-04-18 Python之split函數(shù)的深入理解_python
- 2022-03-16 C#中獲取二維數(shù)組的行數(shù)和列數(shù)以及多維數(shù)組各個(gè)維度的長(zhǎng)度_C#教程
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支