go语言基础—map
1、map的概念
哈希表
1、哈希表是一种巧妙且实用的数据结构。
2、它是一个无序的key/value对的集合,其中所有的key都是不同的,然后通过给定的key可以在常数时间复杂度内检索、更新或删除对应的value。
map
1、在go中,一个map就是一个哈希表的引用
2、map的类型写作map[K]Y,K是key的数据类型,Y是value的数据类型,K与Y可以是不相同的
3、所有的key必须是声明的同一类型,并且必须是支持==比较运算符的,这是为了保证key的独立性
4、所有的value必须是声明的同一类型,没有其他限制
2、map的创建
make函数
// 使用make函数创建的map是一个空map,但不是一个值为nil的map
// 可以继续对它进行存取值等一切正常的map操作
ages := make(map[string]int)
字面量
// 使用字面量的方式,有简短语法:= 和关键字语法var
// map是一个对哈希表的引用,因此当不引用任何哈希表,包括空的哈希表时,map值为nil,即map的零值
// map为nil时,无法进行存取值,因为找不到引用的哈希表
ages := map[string]int // 声明一个map,但是没有初始化,即nil
names := map[string]int{} // 声明一个map,并初始化为空
3、常用方法
3.1 存取值
// 通过[]按key存取值,类似于python的字典
// 通过内置方法delete方法删除值,先访问目标值,再删除
// 访问map值时,若不存在该key,则返回map的零值
func main() {
ages := make(map[string]int)
ages["egon"] = 18 // 添加值到map
ages["nick"] = 19
fmt.Println(ages)
fmt.Println(ages["egon"]) // 从map中取值
delete(ages,"egon") // 删除map中的值
fmt.Println(ages)
fmt.Println(ages["egon"]) // egon不存在,结果为零值
}
3.2 遍历map
禁止对map元素取址操作
1、map中的元素并不是变量
2、map可能随着元素数量的增长而重新分配更大的内存空间,从而可能导致之前的地址无效
_ = &ages["bob"] // compile error: cannot take address of map element
for...range循环遍历
1、使用range风格的for循环,可以遍历map的所有key/value对
2、map是一个对哈希表的引用,而哈希表是一个无序的key/value对的集合,因此map的迭代顺序也是不确定的
3、不同的哈希函数实现也可能导致不同的遍历顺序
4、实际中,对map的遍历时随机的
for name, age := range ages {
fmt.Printf("%s\t%d\n", name, age)
}
5、若要有序遍历,那么需要先将key排序,通过有序的key,可以有序的遍历map,在go中,可以通过sort包的Strings函数对字符串slice进行排序
import "sort"
var names []string
for name := range ages {
names = append(names, name)
}
sort.Strings(names)
for _, name := range names {
fmt.Printf("%s\t%d\n", name, ages[name])
}
3.3 解决默认零值的冲突
1、当访问的map元素不存在时,默认返回零值
2、因此,无法判断到底是不存在返回的零值还是真正的值为零值的元素
解决办法:
// map[K]的方式访问map元素时,有两个返回值,第一个时value,第二个是布尔值,布尔值变量一般命名为ok
age, ok := ages["bob"]
if !ok { /* "bob" is not a key in this map; age == 0. */ }
// 一般用下面的方式连用
if age, ok := ages["bob"]; !ok { /* ... */ }
3.4 比较
map之间也不能进行相等比较,唯一的例外是和nil进行比较,判断两个map是否包含相同的key和value,必须通过一个循环实现,再map长度相同的情况下,逐个比较每个元素
func equal(x, y map[string]int) bool {
if len(x) != len(y) {
return false
}
for k, xv := range x {
if yv, ok := y[k]; !ok || yv != xv {
return false
}
}
return true
}
4、实现set类型的功能
go中没有set类型,但是map中的key是不相同的,可以用map实现类似set的功能

浙公网安备 33010602011771号