Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

基本介绍

带并发安全开关的双向列表。

使用场景

双向链表。

使用方式

import "github.com/gogf/gf/container/glist"

接口文档

https://godoc.org/github.com/gogf/gf/container/glist

基础使用

package main

import (
	"fmt"
	"github.com/gogf/gf/container/glist"
)

func main() {
	// Not concurrent-safe in default.
	l := glist.New()
	// Push
	l.PushBack(1)
	l.PushBack(2)
	e := l.PushFront(0)
	// Insert
	l.InsertBefore(e, -1)
	l.InsertAfter(e, "a")
	fmt.Println(l)
	// Pop
	fmt.Println(l.PopFront())
	fmt.Println(l.PopBack())
	fmt.Println(l)
}

执行后,输出结果:

[-1,0,"a",1,2]
-1
2
[0,"a",1]

链表遍历

该示例中我们将通过读锁和写锁遍历一个并发安全的链表,分别通过RLockFuncLockFunc实现。

package main

import (
	"container/list"
	"fmt"
	"github.com/gogf/gf/container/garray"
	"github.com/gogf/gf/container/glist"
)

func main() {
	// concurrent-safe list.
	l := glist.NewFrom(garray.NewArrayRange(1, 10, 1).Slice(), true)
	// iterate reading from head.
	l.RLockFunc(func(list *list.List) {
		length := list.Len()
		if length > 0 {
			for i, e := 0, list.Front(); i < length; i, e = i+1, e.Next() {
				fmt.Print(e.Value)
			}
		}
	})
	fmt.Println()
	// iterate reading from tail.
	l.RLockFunc(func(list *list.List) {
		length := list.Len()
		if length > 0 {
			for i, e := 0, list.Back(); i < length; i, e = i+1, e.Prev() {
				fmt.Print(e.Value)
			}
		}
	})

    fmt.Println()

    // iterate reading from head using IteratorAsc.
	l.IteratorAsc(func(e *glist.Element) bool {
		fmt.Print(e.Value)
		return true
	})
	fmt.Println()
	// iterate reading from tail using IteratorDesc.
	l.IteratorDesc(func(e *glist.Element) bool {
		fmt.Print(e.Value)
		return true
	})

	fmt.Println()

	// iterate writing from head.
	l.LockFunc(func(list *list.List) {
		length := list.Len()
		if length > 0 {
			for i, e := 0, list.Front(); i < length; i, e = i+1, e.Next() {
				if e.Value == 6 {
					e.Value = "M"
					break
				}
			}
		}
	})
	fmt.Println(l)
}

执行后,输出结果为:

12345678910
10987654321
12345678910
10987654321
[1,2,3,4,5,"M",7,8,9,10]

Push*元素项入栈

使用方式:

Code Block
languagego
package main

import (
	"fmt"
	"github.com/gogf/gf/v2/container/glist"
	"github.com/gogf/gf/frame/g"
)

func main() {
	l := glist.NewFrom(g.Slice{1, 2, 3, 4, 5})

	l.PushBack(6)
	fmt.Println(l)

	l.PushFront(0)
	fmt.Println(l)

	l.PushBacks(g.Slice{7, 8})
	fmt.Println(l)

	l.PushFronts(g.Slice{-2, -1})
	fmt.Println(l)

	// Output:
	// [1,2,3,4,5,6]
	// [0,1,2,3,4,5,6]
	// [0,1,2,3,4,5,6,7,8]
	// [-2,-1,0,1,2,3,4,5,6,7,8]
}

Pop*元素项出栈

package main

import (
	"fmt"
	"github.com/gogf/gf/container/glist"
	"github.com/gogf/gf/frame/g"
)

func main() {
	l := glist.NewFrom(g.Slice{1, 2, 3, 4, 5, 6, 7, 8, 9})

	fmt.Println(l.PopBack())
	fmt.Println(l.PopBacks(2))
	fmt.Println(l.PopFront())
	fmt.Println(l.PopFronts(2))

	// Output:
	// 9
	// [8 7]
	// 1
	// [2 3]
}

Join元素项串连

package main

import (
	"fmt"
	"github.com/gogf/gf/container/glist"
	"github.com/gogf/gf/frame/g"
)

func main() {
	var l glist.List
	l.PushBacks(g.Slice{"a", "b", "c", "d"})

	fmt.Println(l.Join(","))

	// Output:
	// a,b,c,d
}

Remove/Removes/RemoveAll元素移除

Code Block
languagego
package main import ( "fmt" "github.com/gogf/gf/container/glist" "

接口文档

https://pkg.go.dev/github.com/gogf/gf/

frame/g" ) func main() { l := glist.NewFrom(g.Slice{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}) fmt.Println(l.Remove(l.Front())) fmt.Println(l) l.Removes([]*glist.Element{l.Front(), l.Front().Next()}) fmt.Println(l) l.RemoveAll() fmt.Println(l) // Output: // [0,1,2,3,4,5,6,7,8,9] // [1,2,3,4,5,6,7,8,9] // [3,4,5,6,7,8,9] // [] }

JSON序列化/反序列

glist容器实现了标准库json数据格式的序列化/反序列化接口。

  • Marshal
package main
import ( "encoding/json" "fmt" "github.com/gogf/gf/container/glist" "github.com/gogf/gf/frame/g" ) func main() { type Student struct { Id int Name string Scores *glist.List } s := Student{ Id: 1, Name: "john", Scores: glist.NewFrom(g.Slice{100, 99, 98}), } b, _ := json.Marshal(s) fmt.Println(string(b)) }
执行后,输出结果:
``` {"Id":1,"Name":"john","Scores":[100,99,98]} ```

v2/container/glist

相关文档

Children Display
alltrue
excerptTypesimple

  • Unmarshal
package main


import (
    "encoding/json"
    "fmt"
    "github.com/gogf/gf/container/glist"
)


func main() {
    b := []byte(`{"Id":1,"Name":"john","Scores":[100,99,98]}`)
    type Student struct {
        Id     int
        Name   string
        Scores *glist.List
    }
    s := Student{}
    json.Unmarshal(b, &s)
    fmt.Println(s)
}

执行后,输出结果:

{1 john [100,99,98]}

性能测试

https://github.com/gogf/gf/blob/master/container/glist/glist_z_bench_test.go

goos: linux goarch: amd64 pkg: github.com/gogf/gf/container/glist Benchmark_PushBack-4 5000000 268 ns/op 56 B/op 2 allocs/op Benchmark_PushFront-4 10000000 435 ns/op 56 B/op 2 allocs/op Benchmark_Len-4 30000000 44.5 ns/op 0 B/op 0 allocs/op Benchmark_PopFront-4 20000000 71.1 ns/op 0 B/op 0 allocs/op Benchmark_PopBack-4 30000000 70.1 ns/op 0 B/op 0 allocs/op PASS


Panel
titleContent Menu

Table of Contents