Go语言之map练习

map理论基础知识

  • 类似其他语言中的哈希表或者字典,以key-value形式存储数据
  • key必须是支持== 或者 != 比较运算的类型,不可以是函数,map或者slice
  • map查找比线性搜索快很多,但比使用索引访问数据的类型慢100倍
  • map使用make()创建,支持:=这种简写方式

  • make([keyType]valueType, cap), cap表示容量,可省略
  • 超出容量时会自动扩容,但尽量提供一个合理的初始值
  • 使用len()获取元素个数
  • 键值对不存在时自动添加,使用delete()删除某键值对
  • 使用for range 对map和slice进行迭代操作

迭代时,注意事项

//map 练习
package main

import (
    "fmt"
    "sort"
)

func main() {
    //============================方式一:===========================
    //创建一个空的map
    //先声明一个map类型
    var nodeMap map[int]string
    //初始化nodeMap, 全部为空
    nodeMap = map[int]string{}
    fmt.Println(nodeMap)

    fmt.Println("-----------------------------------------------")
    //============================方式二:===========利用make================
    var clusterMap map[int]string = make(map[int]string)
    fmt.Println(clusterMap)

    fmt.Println("-----------------------------------------------")
    //============================方式三:===========利用推断功能================
    operatorMap := make(map[int]string)
    fmt.Println(operatorMap)

    //============================方式四:===========创建时直接初始化================
    //此种方式,不需要使用make
    operatorMap2 := map[int]string{3:"hello", 5:"world"}
    fmt.Println("===>:\t",operatorMap2)

    // ======初始化=====
    nodeMap[1] = "sparkNode"
    nodeMap[2] = "esNode"
    fmt.Println(nodeMap)

    //=======根据键 取出 元素
    nodeName := nodeMap[2]
    fmt.Println(nodeName)

    //======删除键值对
    delete(nodeMap, 1) //根据键值对,进行删除
    fmt.Println(nodeMap)

    fmt.Println("-----------------------------------------------")
    //--------------复杂map的操作-------------------
    //声明一个map类型
    var clusterAppTaskId map[string]map[string]string
    //初始化此map类型
    clusterAppTaskId = make(map[string]map[string]string)

    taskId, ok := clusterAppTaskId["spark-beijing"]["/spark-beijing/app-uewqr"]

    if !ok {
        //每一级别的map都有进行初始化,编译时是找不到的,只有运行时,才能发现
        clusterAppTaskId["spark-beijing"] = make(map[string]string)
    }

    clusterAppTaskId["spark-beijing"]["/spark-beijing/app-uewqr"] = "app-ewr-spark-taskid-001"
    taskId, ok = clusterAppTaskId["spark-beijing"]["/spark-beijing/app-uewqr"]

    fmt.Println(taskId, ok)

    fmt.Println("-----------------------------------------------")
    //--------------迭代操作-------------------
    //for i, v := range slice {
    //
    //}
    //i, 表示下标,v表示对应的值,是拷贝的值
    //要特别注意,对v的任何修改,都不影响原值,
    // map类型也是,不会影响原值的

    //例如,下面的例子,就是对v的操作后,不会对sm产生影响的
    //因此,不建议使用这种方式
    sm := make([]map[int]string, 5)
    for _, v := range sm {
        v = make(map[int]string)
        v[1] = "ok"
        fmt.Println(v)
    }

    fmt.Println(sm)
    fmt.Println("-----------------------------------------------")
    //下面的修改,原值
    for i := range sm {
        sm[i] = make(map[int]string)
        sm[i][2] = "spark"
        fmt.Println(sm[i])
    }

    fmt.Println(sm)

    fmt.Println("-----------------------------------------------")
    //---------------------------------
    //map是无序的,如何按照键从小到大获取map中的值
    //需要生成一个切片,来存储map的键
    //将键按照从小到大排序,然后,再根据键去取值
    marathonApp := map[int]string{1: "spark", 3: "es", 8: "ftp", 7:"hadoop", 4: "k8s", 2: "docker"}
    len := len(marathonApp)
    //生成一个切片,来存储键
    kSlice := make([]int, len)
    // 声明一个计数器,用于初始化切片时使用
    var i int = 0
    for k, _ := range marathonApp {
        kSlice[i] = k
        i++
    }
    fmt.Println("键排序前:\t", kSlice)

    //切片是引用传递,因此,下面排序后,不需要返回值进行接收
    sort.Ints(kSlice)
    fmt.Println("键排序后:\t", kSlice)

    fmt.Println("根据键按照从小到大,依次取出对应的值")
    //下面,开始迭代marathonApp,就可以按照键的从小到大,依次取出值了
    for _, v := range kSlice {
        //这里一定要注意,是用值,而不是 kSlice的下标
        fmt.Println(marathonApp[v])
    }

}

    fmt.Println("-----------------------------------------------")
    //------------------如何将map类型的键与值对换呢---------------
    kafkaClusterIdNameMap := map[int]string{1: "kafka-beijing", 2: "kafka-sjz", 4: "kafka-shanghai", 5: "kafka-tianjin", 3: "kafka-yizhuang"}
    kafkaNameClusterIdMap := make(map[string]int)
    for k, v := range kafkaClusterIdNameMap {
        kafkaNameClusterIdMap[v] = k
    }
    fmt.Println("kafkaClusterIdNameMap:\t", kafkaClusterIdNameMap)
    fmt.Println("kafkaNameClusterIdMap:\t", kafkaNameClusterIdMap)

原文地址:http://blog.51cto.com/xingej/2102229

时间: 2024-09-29 21:42:08

Go语言之map练习的相关文章

看懂Gradle脚本(1)- Groovy语言的Map语法糖

这一系列文章是写给刚开始使用Gradle,并且对Groovy语法不是特别了解的Java程序员看的. 本篇文章的目标是解释清楚下面这行Gradle脚本: apply plugin: 'java' 行尾的分号是可选的 用过JavaScript语言的人对这个语法糖应该比较熟悉,下面是补上分号后的脚本: apply plugin: 'java'; Map字面量(Literal) Java语言只有基本类型.String和数组是有字面量的,如下所示: boolean b = false; int i = 1

Go语言之Map

Map是一种无序的键值对的集合,它主要通过Key来快速检索数据,Go语言中用它来提供哈希表的功能. Map是一种数据结构,它是一个集合,用于存储一系列无序的键值对.它是基于键存储的,键就像一个索引一样,这也是Map强大的地方.可以快速检索数据,键指向与该键关联的值. 内部实现 Map是基于散列表来实现的,就是我们常说的Hash表.所以我们每次迭代Map的时候,打印的Key和Value是无序的,每次迭代的都不一样,即使我们按照一定的顺序存在也不行. Map的散列表包含一组桶,每次存储和查找键值对的

【Go语言】【10】GO语言的map

GO语言中的复合类型除了数组.切片之外,还有一个map:说起map估计大家都不陌生,因为在Java.C++等语言中有它的身影,它以<key,value>的形式为程序员提供服务. 从图中也可以看出:内存中存储了六个城市信息,其中key是城市电话区号,value是城市名称.对于城市电话区号(key)是唯一的,这样方便程序员对城市名称(value)进行增.删.改.查等操作:另外<key,value>之间也存在一定的关联,即图中的箭头,但这种关联关系对GO语言的初学者来说并不需要特别关心.

go语言学习--map的并发

go提供了一种叫map的数据结构,可以翻译成映射,对应于其他语言的字典.哈希表.借助map,可以定义一个键和值,然后可以从map中获取.设置和删除这个值,尤其适合数据查找的场景.但是map的使用有一定的限制,如果是在单个协程中读写map,那么不会存在什么问题,如果是多个协程并发访问一个map,有可能会导致程序退出,并打印下面错误信息: fatal error: concurrent map read and map write 上面的这个错误不是每次都会遇到的,如果并发访问的协程数不大,遇到的可

【Go语言】map在goroutine通信中的使用

简介 本篇文章的主要内容是解决go语言map在使用中遇到的两个问题 一.cannot assign to struct field https://haobook.readthedocs.io/zh_CN/latest/periodical/201611/zhangan.html 二.fatal error:concurrent map read and map write https://blog.csdn.net/skh2015java/article/details/60334091 原文

深度解密Go语言之 map

目录 什么是 map 为什么要用 map map 的底层如何实现 map 内存模型 创建 map 哈希函数 key 定位过程 map 的两种 get 操作 如何进行扩容 map 的遍历 map 的赋值 map 的删除 map 进阶 可以边遍历边删除吗 key 可以是 float 型吗? 总结 参考资料 这篇文章主要讲 map 的赋值.删除.查询.扩容的具体执行过程,仍然是从底层的角度展开.结合源码,看完本文一定会彻底明白 map 底层原理. 我要说明的是,这里对 map 的基本用法涉及比较少,我

Go语言 基础 map

Go语言基础之map Go语言中提供的映射关系容器为map,其内部使用散列表(hash)实现. map map是一种无序的基于key-value的数据结构,Go语言中的map是引用类型,必须初始化才能使用. map定义 Go语言中 map的定义语法如下: map[KeyType]ValueType 其中, KeyType:表示键的类型. ValueType:表示键对应的值的类型. map类型的变量默认初始值为nil,需要使用make()函数来分配内存.语法为: make(map[KeyType]

GO语言 切片 map 字符串

切片 1.什么是切片 切片本身不拥有任何数据,它们只是对现有数组的引用. 2.切片的定义 1.方式1:由数组切出来:var 变量名 []元素类型 = 数组名[开始值:结束值] //1.定义数组 var a [8]int=[8]int{1,2,3,4,5,6,7,8} //2.定义切片,注意[]中没有数字 var b []int=a[2:6] fmt.Println(b) // [3 4 5 6] //更多用法,没有步长 var a [8]int=[8]int{1,2,3,4,5,6,7,8} b

Go语言 sync.Map(在并发中使用)

Go语言中的 map 在并发情况下,只读是线程安全的,同时读写是线程不安全的. 需要并发读写时,一般的做法是加锁,但这样性能并不高,Go语言在 1.9 版本中提供了一种效率较高的并发安全的 sync.Map,sync.Map 和 map 不同,不是以语言原生形态提供,而是在 sync 包下的特殊结构. sync.Map 有以下特性: 无须初始化,直接声明即可. sync.Map 不能使用 map 的方式进行取值和设置等操作,而是使用 sync.Map 的方法进行调用,Store 表示存储,Loa