Map 是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值 Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,我们无法决定它的返回顺序,这是因为 Map 是使用 hash 表来实现的
定义 Map
可以使用内建函数 make 也可以使用 map 关键字来定义 Map:
// 声明变量,默认 map 是 nil
var map_variable map[key_data_type]value_data_type
// 使用 make 函数
map_variable := make(map[key_data_type]value_data_type)
如果不初始化 map,那么就会创建一个 nil map, 就不能用来存放键值对
下面实例演示了创建和使用map:
package main
import "fmt"
func main() {
var countryCapitalMap map[string]string //创建集合
countryCapitalMap = make(map[string]string)
// map插入key - value对,各个国家对应的首都
countryCapitalMap [ "France" ] = "巴黎"
countryCapitalMap [ "Italy" ] = "罗马"
countryCapitalMap [ "Japan" ] = "东京"
countryCapitalMap [ "India " ] = "新德里"
//使用键输出地图值
for country := range countryCapitalMap {
fmt.Println(country, "首都是", countryCapitalMap [country])
}
//查看元素在集合中是否存在
capital, ok := countryCapitalMap [ "American" ] //如果确定是真实的,则存在,否则不存在
if (ok) {
fmt.Println("American 的首都是", capital)
} else {
fmt.Println("American 的首都不存在")
}
}
/*
以上实例运行结果为:
France 首都是 巴黎
Italy 首都是 罗马
Japan 首都是 东京
India 首都是 新德里
American 的首都不存在
*/
delete() 函数
delete() 函数用于删除集合的元素, 参数为 map 和其对应的 key。实例如下:
package main
import "fmt"
func main() {
// 创建map
countryCapitalMap := map[string]string{"France": "Paris", "Italy": "Rome", "Japan": "Tokyo", "India": "New delhi"}
fmt.Println("原始地图")
for k,country := range countryCapitalMap {
fmt.Println(country, "首都是:", countryCapitalMap[k])
}
//删除元素
delete(countryCapitalMap, "France")
fmt.Print("\n法国条目被删除\n\n")
fmt.Println("删除元素后地图")
for k := range countryCapitalMap {
fmt.Println(k, "首都是:", countryCapitalMap[k])
}
}
/*
以上实例运行结果为:
原始地图
France 首都是: Paris
Italy 首都是: Rome
Japan 首都是: Tokyo
India 首都是: New delhi
法国条目被删除
删除元素后地图
Italy 首都是: Rome
Japan 首都是: Tokyo
India 首都是: New delhi
*/
基于go实现简单 HashMap,暂未做key值的校验
package main
import (
"fmt"
)
type HashMap struct {
key string
value string
hashCode int
next *HashMap
}
var table [16](*HashMap)
func initTable() {
for i := range table{
table[i] = &HashMap{"","",i,nil}
}
}
func getInstance() [16](*HashMap){
if(table[0] == nil){
initTable()
}
return table
}
func genHashCode(k string) int{
if len(k) == 0{
return 0
}
var hashCode int = 0
var lastIndex int = len(k) - 1
for i := range k {
if i == lastIndex {
hashCode += int(k[i])
break
}
hashCode += (hashCode + int(k[i]))*31
}
return hashCode
}
func indexTable(hashCode int) int{
return hashCode%16
}
func indexNode(hashCode int) int {
return hashCode>>4
}
func put(k string, v string) string {
var hashCode = genHashCode(k)
var thisNode = HashMap{k,v,hashCode,nil}
var tableIndex = indexTable(hashCode)
var nodeIndex = indexNode(hashCode)
var headPtr [16](*HashMap) = getInstance()
var headNode = headPtr[tableIndex]
if (*headNode).key == "" {
*headNode = thisNode
return ""
}
var lastNode *HashMap = headNode
var nextNode *HashMap = (*headNode).next
for nextNode != nil && (indexNode((*nextNode).hashCode) < nodeIndex){
lastNode = nextNode
nextNode = (*nextNode).next
}
if (*lastNode).hashCode == thisNode.hashCode {
var oldValue string = lastNode.value
lastNode.value = thisNode.value
return oldValue
}
if lastNode.hashCode < thisNode.hashCode {
lastNode.next = &thisNode
}
if nextNode != nil {
thisNode.next = nextNode
}
return ""
}
func get(k string) string {
var hashCode = genHashCode(k)
var tableIndex = indexTable(hashCode)
var headPtr [16](*HashMap) = getInstance()
var node *HashMap = headPtr[tableIndex]
if (*node).key == k{
return (*node).value
}
for (*node).next != nil {
if k == (*node).key {
return (*node).value
}
node = (*node).next
}
return ""
}
func main() {
getInstance()
put("a","a_put")
put("b","b_put")
put("c","c_put")
fmt.Println(get("a"),get("b"),get("c"))
}
/*
a_put b_put c_put
*/