返回顶部
扩大
缩小

人外有人天外有天

Go Map

Go中内置类型,其使用hash表实现,为引用类型。

无序键值对集合,通过key(类似索引)快速检索数据。

Map是什么

Map是一种数据结构,是一个集合,用于存储一系列无序的键值对。

基于键存储的,可以快速快速检索数据,键指向与该键关联的值

Map内部实现

Map存储的是什么?Map存储的是无序的键值对集合

Map基于什么?基于散列表(hash表),故每次迭代Map,打印的key和value是无序的,每次迭代不一样。

Map散列表特点是?包含一组桶,每次存储和查找键值对的时候,都要先选择一个桶。

如何选择桶?把指定的键传给散列函数,就可索引到相应的桶,进而找到对应的键值。

这种方式的好处是?存储的数据越多,索引分布越均匀,所以我们访问键值对的速度也就越快

Map声明和初始化

Map的创建方式?两种方法:make函数,map字面量。

法一:make函数

m:=make(map[string]int)
m["张三"] = 21

 

法二:map字面量创建和初始化

m:= map[string]int{"张三":21}
m2:= map[string]int{"张三":21,"李四":22}
m3:= map[string]int{} //空map

 

如何创建一个nil的map? var m4 map[string]int 这样我们是不能操作存储键值对的,必须要初始化后才可以

var m4 map[string]int
m4 = make(map[string]int)
m4["张三"] = 21
fmt.Println(m4)    // map[张三:21]

 

Map的键可以是

除了slice,map,function的内建类型都可以作为key

Struct不包含上述字段,可以作为key

任何值:内置的类型、结构类型。原则是:可以使用 == 进行比较。

故切片、函数以及含有切片的结构类型就不能用于Map的键,因为其具有引用语义,不可比较。

使用Map

Map通过键来使用,类似数组切片通过索引。

delete(map, key) 函数用于删除集合的元素, 参数为 map 和其对应的 key。删除函数不返回任何值。

注:

make 用于内建类型(map、slice 和channel)的内存分配

内建函数make(T, args),make只能创建slice、map和channel,并且返回一个有初 始值(非零)的T类型,而不是*T

new 用于各种类型的内存分配

内建函数new(T)与其他语言相同:分配了零值填充的T类型的内存空间,它返回了一个指针*T,指向新分配

m:= make(map[string]int)
m["张三"] = 21
//获取一个Map键的值
age := m["张三"]
fmt.Println("张三的年龄",age)
//如果张三存在 对值修改  注:Map提供了一个检测键值对是否存在的方法
age1,exists := m["李四"]
if(exists){
    fmt.Println("李四的年龄",age1)
}else {
    fmt.Println("没有李四")
}
//删除一个Map的键值对用delete 注:delete可以删除不存在的键,只是没有任何作用
delete(m,"张三")
fmt.Println(m)

 

输出:

张三的年龄 21
没有李四
map[]

 

如何遍历Map?for range

使用range遍历key,或者遍历key,value对

不保证遍历顺序,如需顺序,需手动对key排序

使用 len(map) 获得元素个数

func main() {
    m := map[string]int{"张三": 21}
    for key, value := range m {
        fmt.Println(key, value)
    }
    sortOrder()
}

func sortOrder(){
    m1 := map[string]int{"张三": 22,"王五": 60, "李六": 33}
    var names []string
    for name := range m1 {
        names = append(names, name)
    }
    sort.Strings(names) //排序
    for _, key := range names {
        fmt.Println(key, m1[key])
    }
}

 

输出:

张三 21
张三 22
李六 33
王五 60

 

在函数间传递Map

传递的不是一个Map副本。

func main() {
    m2 := map[string]int{"王五": 60, "张三": 21}
    modify(m2)
    fmt.Println(m2["张三"]) //10
}

func modify(dict map[string]int) {
    dict["张三"] = 10
}

 

posted on 2018-07-29 16:54  笔记是研究的开始  阅读(320)  评论(0编辑  收藏  举报

导航