简介
Go的标准包container中包含了常用的容器类型,包括conatiner/list,container/heap,container/ring。本篇介绍conatiner/list。

conatiner/list实现了一个双向链表。使用起来与其他语言的动态列表非常相似,3秒钟便可入门。

3秒钟入门

package main

import (
"container/list"
"fmt"
) func main() {
nums := list.New()
nums.PushBack(1)
nums.PushBack(2)
nums.PushBack(3)
for e := nums.Front(); e != nil; e = e.Next() {
fmt.Println(e.Value)
}
}

包中有什么
包里只导出了两个类型和一个函数:

表示列表的List类型
表示列表元素的Element类型

创建List的函数
container/list––––––––––––––container/list_
// 表示双向列表
type List struct{ ... } // 表示列表中的元素
type Element struct{ ... } // 创建List
func New() *List

  

下面详细讲解该包的用法。

Element
先来看看Element类型:

container/list––––––––––––––container/list_
type Element struct {
Value interface{} // 存储在该元素中的值
}

可以看到值的类型为 interface{},因此Element可以存储任何值。

创建List
使用New来创建List,函数原型如下:

container/list––––––––––––––container/list_
func New() *List

示例:

oll := list.New()
添加元素
List导出了六个方法用于添加元素: container/list––––––––––––––container/list_
// 追加新元素到末尾,返回该元素指针
func (l *List) PushBack(v interface{}) *Element
// 追加另一个列表到末尾
func (l *List) PushBackList(other *List)
// 添加新元素到开头,返回该元素指针
func (l *List) PushFront(v interface{}) *Element
// 添加另一个列表到开头
func (l *List) PushFrontList(other *List)
// 在mark后面插入新元素,返回新元素指针
func (l *List) InsertAfter(v interface{}, mark *Element) *Element
// 在mark前插入新元素,返回新元素指针
func (l *List) InsertBefore(v interface{}, mark *Element) *Element

示例:

// 追加元素到末尾
coll.PushBack(1)
coll.PushBack("Gopher") // 添加元素到开头
coll.PushFront("Cynhard")
two := coll.PushFront(2) // 插入元素到two之前
before2 := coll.InsertBefore("Before2", two) // 插入元素到two之后
after2 := coll.InsertAfter("After2", two) coll2 := list.New()
coll2.PushBack(3)
coll2.PushFront("Tomcat") // 追加另外一个列表到末尾
coll.PushBackList(coll2) // 添加另外一个列表到开头
coll.PushFrontList(coll2)

应注意到一个列表中的元素的值的类型不必一致。

移动元素
List导出了四个方法用于移动元素:

container/list––––––––––––––container/list_
// 移动e到mark之后
func (l *List) MoveAfter(e, mark *Element)
// 移动e到mark之前
func (l *List) MoveBefore(e, mark *Element)
// 移动e到末尾
func (l *List) MoveToBack(e *Element)
// 移动e到开头
func (l *List) MoveToFront(e *Element)

注意e和mark都必须是l的内的元素,否则该函数不执行任何动作。

示例:

two := coll.PushFront(2)
before2 := coll.InsertBefore("Before2", two)
after2 := coll.InsertAfter("After2", two) // 将before2移动到two的后面
coll.MoveAfter(before2, two)
// 将after2移动到two的前面
coll.MoveBefore(after2, two)
// 将before2移动到开头
coll.MoveToFront(before2)
// 将after2移动到末尾
coll.MoveToBack(after2)

访问元素

List导出了Back()和Front()返回结尾和开头元素:

container/list––––––––––––––container/list_
// 返回结尾元素
func (l *List) Back() *Element
// 返回开头元素
func (l *List) Front() *Element

示例:

fmt.Println(coll.Front().Value) // 打印开头元素的值
fmt.Println(coll.Back().Value) // 打印结尾元素的值

遍历列表
Element导出了两个方法Prev()和Next()用以访问前一个或后一个元素:

container/list––––––––––––––container/list_
// 返回下一个元素,如果没有下一个元素,返回nil
func (e *Element) Next() *Element
// 返回前一个元素,如果没有前一个元素,返回nil
func (e *Element) Prev() *Element

示例:

// 顺序遍历
for e := coll.Front(); e != nil; e = e.Next() {
fmt.Print(e.Value, " ")
}
fmt.Println()
// 逆序遍历
for e := coll.Back(); e != nil; e = e.Prev() {
fmt.Print(e.Value, " ")
}
fmt.Println()

获取列表长度

container/list––––––––––––––container/list_
func (l *List) Len() int

示例:

mt.Println(coll.Len())
移除元素
container/list––––––––––––––container/list_
// 移除e,返回e的值
func (l *List) Remove(e *Element) interface{}
// 清空列表
func (l *List) Init() *List

示例:

coll := list.New()
two := coll.PushFront(2)
coll.Remove(two) // 移除two
coll.Init() // 清空列表

完整示例

package main

import (
"container/list"
"fmt"
) func printList(coll *list.List) {
for e := coll.Front(); e != nil; e = e.Next() {
fmt.Print(e.Value, " ")
}
fmt.Println()
} func printListR(coll *list.List) {
for e := coll.Back(); e != nil; e = e.Prev() {
fmt.Print(e.Value, " ")
}
fmt.Println()
} func main() {
coll := list.New() coll.PushBack(1)
coll.PushBack("Gopher") coll.PushFront("Cynhard")
two := coll.PushFront(2) before2 := coll.InsertBefore("Before2", two)
after2 := coll.InsertAfter("After2", two) coll.MoveAfter(before2, two)
coll.MoveBefore(after2, two)
coll.MoveToFront(before2)
coll.MoveToBack(after2) coll2 := list.New()
coll2.PushBack(3)
coll2.PushFront("Tomcat") coll.PushBackList(coll2)
coll.PushFrontList(coll2) printList(coll)
printListR(coll) fmt.Println(coll.Front().Value)
fmt.Println(coll.Back().Value) fmt.Println(coll.Len()) coll.Remove(two) printList(coll) coll.Init()
printList(coll)
}

  

Go标准容器之List的更多相关文章

  1. [知识点]C++中STL容器之map

    UPDATE(20190416):写完vector和set之后,发现不少内容全部引导到map上了……于是进行了一定的描述补充与更正. 零.STL目录 1.容器之map 2.容器之vector 3.容器 ...

  2. Java并发编程:并发容器之CopyOnWriteArrayList(转载)

    Java并发编程:并发容器之CopyOnWriteArrayList(转载) 原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW ...

  3. Java并发编程:并发容器之ConcurrentHashMap(转载)

    Java并发编程:并发容器之ConcurrentHashMap(转载) 下面这部分内容转载自: http://www.haogongju.net/art/2350374 JDK5中添加了新的concu ...

  4. Java并发编程:并发容器之ConcurrentHashMap

    转载: Java并发编程:并发容器之ConcurrentHashMap JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的 ...

  5. Java并发编程:并发容器之CopyOnWriteArrayList

    转载: Java并发编程:并发容器之CopyOnWriteArrayList Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个 ...

  6. Java 容器之Hashset 详解

    Java 容器之Hashset 详解.http://blog.csdn.net/nvd11/article/details/27716511

  7. 【转】Java并发编程:并发容器之CopyOnWriteArrayList

    Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改, ...

  8. 【转】Java并发编程:并发容器之ConcurrentHashMap

    JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的访问都串行化了,这样保证了线程的安全性,所以这种方法的代价就是严重降低了 ...

  9. C++顺序容器之list初探

    C++顺序容器之list初探 双向链表,支持双向顺序访问.在list中任何位置进行插入和删除速度都很快. list不支持随机访问,为了访问一个元素,必须遍历整个容器. #include<iost ...

随机推荐

  1. 在w3cschool学完html,css,javascript,jquery以后,还是不会做前端怎么办?

    w3cschool是一个非盈利性的在线技术学习网站,提供按W3C标准编写的基础教程.完整的看完w3cschool上面的手册,可以基本掌握编程语法.基础性的东西通常都会比较零散,因此,在学习一段时间后, ...

  2. 第二课 GCC入门之静态库以及共享库

    序言: 前面一课讲了gcc的简单入门,包括gcc编译步骤:预处理:编译:汇编:链接.今天这节课就来讲下linux的库也欢迎大家吐糟共同学习. 原理: linux系统中分为2种库:静态库和共享库.静态库 ...

  3. Qios RibbonForm QRibbonCaption添加qRibbonApplicationButton无法最大化问题

    winform 用了Qios DevSuite系列的控件. RibbonForm中QRibbonCaption添加qRibbonApplicationButton之后无法最大化. 修改qRibbonA ...

  4. SweetWeather wpf天气预报源代码

    数据来源于中国天气网(www.weather.com.cn)和天气预报网(www.tianqiyubao.com) 主要是对中国天气网和天气预报网接口数据做解析.结合MVVM框架实现. 主界面:   ...

  5. Refseq,accssion #,gi ,Ensembl的关系

    accession编号的分子类型代号: Ensembl是2000年就开始开发的基因组自动注释软件,起初是只对真核生物基因组,2009年后开始对植物,细菌等开放.既然要注释,就要有注释对象(基因,转录本 ...

  6. 2062326 齐力锋 实验二《Java面向对象程序设计》实验报告

    北京电子科技学院(BESTI) 实     验    报     告 课程:   程序设计与数据结构           班级:      1623           姓名:  齐力锋      学 ...

  7. Spring混合配置

    Spring混合配置 一.在JavaConfig中引入其他配置 在JavaConfig中引入JavaConfig配置 使用@Import({OtherConfig1.class,OtherConfig ...

  8. 用WAR的方式部署SpringBoot项目

    接SpringBoot 快速入门(Eclipse) 步骤一:部署方式 Springboot 和 web 应用程序不一样,其本质上是一个 Java 应用程序,那么又如何部署呢? 通常来说,Springb ...

  9. Mac 使用技巧分享

    1. 快捷键开启speech功能: System Preferences -> Ditaction&Speech ->Text to Speech ->Select 'Spe ...

  10. windchill相关功能操作

    1.创建产品   2.创建文件夹   3.创建文档   4.创建用户账号   5.创建组   6.创建更改请求   7.创建部件新视图版本   8.创建可重用属性和全局枚举   9.在组织内分配上下文 ...