Go语言 - map

Go语言中提供的映射关系容器为map,其内部使用散列表(hash)实现。

map是一种无序的基于key-value的数据结构,Go语言中的map是引用类型,必须初始化才能使用。

map内的键值对是无序的

map定义

Go语言中 map的定义语法如下:

map[KeyType]ValueType
  • KeyType:表示键的类型。
  • ValueType:表示键对应的值的类型。

map类型的变量默认初始值为nil,需要使用make()函数来分配内存初始化。语法为:

make(map[KeyType]ValueType, [cap])

map初始化

  • 方式一 :先声明再初始化

package main

import "fmt"

func main()  {
    // 声明map
    var m map[string]int
    fmt.Println(m == nil)  // true 引用类型只声明不初始化那么它就等于nil
    // 初始化map
    m = make(map[string]int, 5)  // 为m申请内存,m的容量是5
    fmt.Println(m == nil)  // false
}
  • 方式二 : 声明同时初始化

package main

import "fmt"

func main()  {
    // 声明的同时初始化map
    m1 := map[int]bool{
        1:true,
        2:false,
    }
    fmt.Println(m1)  // map[1:true 2:false]
}

 

其中cap表示map的容量,该参数虽然不是必须的,但是我们应该在初始化map的时候就为其指定一个合适的容量。

 map使用

基本使用 添加键值对

map中的数据都是成对出现的

func main()  {
    m := make(map[string]int, 5) 
    // map中添加键值对
    m["熊大"] = 100
    m["熊二"] = 200
    fmt.Println(m)  // map[熊二:200 熊大:100]
    fmt.Printf("m:%#v \n", m)  // m:map[string]int{"熊二":200, "熊大":100}
    fmt.Printf("m:%T \n", m)  // m:map[string]int
}

判断某个键是否存在

Go语言中有个判断map中键是否存在的特殊写法,格式如下:

value, ok := map[key]
// key存在map中, value就是key的值, ok为true
// key不存在map中,value就是map值的默认值, ok为false

 eg:

func main()  {
    course := map[string]int{
        "熊大": 100,
        "熊二": 90,
    }
    value, ok :=course["光头强"]
    if ok {
        fmt.Println("光头强存在course中", value, ok)
    }else{
        fmt.Println("光头强不在course中", ok)  // 光头强不在course中 0 false
    }
}

map的遍历

Go语言中使用for range遍历map。

  • 遍历map中的键值对

func main()  {
    course := map[string]int{
        "熊大": 100,
        "熊二": 90,
    }
    for k, v := range course{
        fmt.Printf("键:%s, 值:%d \n", k, v)
    }
}
  •  遍历map中的key

func main()  {
    course := map[string]int{
        "熊大": 100,
        "熊二": 90,
    }
    for k := range course{
        fmt.Println(k)
    }
}
  •  遍历map中的value

func main()  {
    course := map[string]int{
        "熊大": 100,
        "熊二": 90,
    }
    for _, v := range course{
        fmt.Println(v)
    }
}

delete()函数删除键值对

使用delete()内建函数从map中删除一组键值对,delete()函数的格式如下:

delete(map, key)
  • map:表示要删除键值对的map
  • key:表示要删除的键值对的键
func main()  {
    course := map[string]int{
        "熊大": 100,
        "熊二": 90,
    }
    delete(course, "熊大")
    // delete(course, "光头强") 
    fmt.Println(course)  // map[熊二:90]
}

注意: 当要删除的key不在map中时,map不做任何改变

按照指定顺序遍历map

package main

import (
    "math/rand"  // 导入 rand
    "sort"  // 导入 sort
    "fmt"
)
func main()  {
    // 按照某个固定顺序遍历map
    course := make(map[string]int, 10)
    // 循环添加10个键值对
    for i :=0 ; i < 10; i++{
        key := fmt.Sprintf("stu%02d", i)
        value := rand.Intn(10)  // 随机0-9之间的整数
        course[key] = value
    }
    for k, v := range course{
        fmt.Println(k, v)
    }
    // 按照key从小到大的顺序遍历course
    // 1.先取出所有的key存放到切片中
    keys := make([]string, 0 , 30)  // 长度0, 容量30
    for k := range course{
        keys = append(keys, k)  // 将遍历出来的k追加到keys中
    }
    // 2. 对keys做排序
    sort.Strings(keys)  // keys中的数据类型是string,此时的keys是一个有序切片
    // 3. 按照排序后的keys对course排序
    for _, key :=  range keys{
        fmt.Println(key, course[key])
    }
}

元素为map类型的切片

func main()  {
    // 元素为map类型的切片
    var mapSlice = make([]map[string]int, 3, 3)  // 只是完成了切片的初始化
    fmt.Println(mapSlice)  // map[] map[] map[]]
    fmt.Println(mapSlice[0] == nil)  // true
    // 需要完成内部map的初始化
    mapSlice[0] = make(map[string]int, 8)
    mapSlice[0]["熊大"] = 10
    fmt.Println(mapSlice)  // [map[熊大:10] map[] map[]]
}

值为切片类型的map

func main()  {
    // 值为slice的map
    var sliceMap = make(map[string][]int, 8)  // 只是完成了map的初始化
    v, ok := sliceMap["熊大"]
    if ok{
        fmt.Println(v)
    }else{
        // 当sliceMap中没有熊大这个key时
        sliceMap["熊大"] = make([]int, 5)  // 完成对slice的初始化
        sliceMap["熊大"][0] = 1
        sliceMap["熊大"][1] = 2
        sliceMap["熊大"][3] = 3
    }
      fmt.Printf("%#v \n", sliceMap)  // map[string][]int{"熊大":[]int{1, 2, 0, 3, 0}}
    for k,v := range sliceMap{
        fmt.Println(k, v)  // 熊大 [1 2 0 3 0]
    }
}

通过map实现set

func main() {
    //集合
    //可以放值,如果重复了,放不进去
    //可以获取长度
    //判断一个值是否在集合内
    //把集合内所有元素打印出来
    
    var m map[string]bool=make(map[string]bool)
    m["lqz"]=true
    m["egon"]=true
    
    m["lqz"]=true
    
    fmt.Println(len(m))
    //"aa"是否在集合内
    if m["aa"]{
        fmt.Println("在里面")
    }else {
        fmt.Println("不再")
    }
    for k,_:=range m{
        fmt.Println(k)
    }


}

 

posted @ 2019-11-25 22:05  waller  阅读(134)  评论(0编辑  收藏  举报