Go与Java(10) Go和Java微观对比-9

141 阅读2分钟

29.Go中的map和Java中的HashMap

Go中的map也是一个存储key-value,键值对的这么一种数据结构。

我们来看下如何使用:

如何创建一个map?(map是引用类型,默认值是nil,必须用make为其创建才能使用)

创建一个map必须要用make,否则会是nil

格式为: make(map[key类型]value类型) (下面有代码示例)

往Go中的map赋值添加元素用 【 map变量名称[key] = value 】 的方式

示例1:创建map以及添加元素

package main


import "fmt"


func main() {
   //创建一个map必须要用make,否则会是nil
   //格式为:  make(map[key类型]value类型)
   //Java中:   Map<String,Integer> myMap = new HashMap<>();
   myMap := make(map[string]int)
   //往Go中的map赋值添加元素用 【 map变量名称[key] = value 】 的方式
   //区别于Java中的: myMap.put("li_age",20);
   myMap["li_age"] = 20
   myMap["hong_age"] = 30
   //打印一下map
   fmt.Println(myMap)
}

 

我们从map中取值得格式为: 【 mapValue := map变量名[key]】  

当我们填写的key在map中找不到时返回对应的value默认值,int是0,引用类型是nil

当我们的key取不到对应的值,而value的类型是一个int类型,我们如何判断这个0是实际值还是默认值呢

此时我们需要同时取两个值  

通过map的key取出两个值,第二个参数为bool类型,false为该值不存在,true为成功取到值

参考下面:  

示例2:从map中取值

 

package main


import "fmt"


func main() {
   //创建一个map必须要用make,否则会是nil
   //格式为:  make(map[key类型]value类型)
   //Java中:   Map<String,Integer> myMap = new HashMap<>();
   myMap := make(map[string]int)
   //往Go中的map赋值添加元素用 【 map变量名称[key] = value 】 的方式
   //区别于Java中的: myMap.put("li_age",20);
   myMap["li_age"] = 20
   myMap["hong_age"] = 30
   //打印一下map
   fmt.Println(myMap)
   //不存在的值
   fmt.Println(myMap["no"])


   //当我们的key取不到对应的值,而value的类型是一个int类型,我们如何判断这个0是实际值还是默认值呢
   //此时我们需要同时取两个值
   //通过map的key取出两个值,第二个参数为bool类型,false为该值不存在,true为成功取到值
   value,existsValue := myMap["no"]
   if !existsValue {
      fmt.Println("此值不存在")
   } else {
      fmt.Printf("value = %d",value)
   }
}

 

Go中因为返回值可以是两个,所以的map遍历很简单,不像java还得弄一个Iterator对象再逐个获取,它一次两个都能取出来,用for搭配range即可实现。

 

示例3:遍历

 

package main


import "fmt"


func main() {
   myMap := make(map[string]int)
   myMap["num1"] = 1
   myMap["num2"] = 2
   myMap["num3"] = 3
   myMap["num4"] = 4
   myMap["num5"] = 5
   myMap["num6"] = 6
   //遍历key,value
   for key,value := range myMap {
      fmt.Println(key,value)
   }
   //写一个参数的时候只取key
   for key := range myMap {
      fmt.Println(key)
   }
   //如果只想取value,就需要用到之前的_标识符进行占位丢弃
   for _,value := range myMap {
      fmt.Println(value)
   }
}

 

删除函数:用内置函数delete删除

 

示例4:删除map元素

 

package main


import "fmt"


func main() {
   myMap := make(map[string]int)
   myMap["num1"] = 1
   myMap["num2"] = 2
   myMap["num3"] = 3
   myMap["num4"] = 4
   myMap["num5"] = 5
   myMap["num6"] = 6
   //第二个参数为删除的key
   delete(myMap,"num6")
   //此时已经没有值了,默认值为0
   fmt.Println(myMap["num6"])
}

 

在Java中有一些复杂的Map类型,比如:

Map<String,Map<String,Object>> data = new HashMap<>();

实际上,在Go语言中,也有复杂的类型,我们举几个代码示例

 

示例5:

 

package main


import "fmt"


func main() {
   //由map组成的切片
   //第一部分 make[] 声明切片
   //第二部分 map[string]int  声明该切片内部装的单个类型是map
   //第三部分 参数 5 表示该切片的长度和容量都是5
   //长度是用索引能取到第几个元素,索引不能超过长度-1,分配长度后都是默认值,int是0,引用类型是nil
   //容量至少比长度大,能索引到几个+未来可添加元素个数(目前没有任何东西,看不见)= 切片容量
   //make([]切片类型,切片长度,切片容量)
   //make([]切片类型,切片长度和容量等同)
   slice := make([]map[string]int,5,10)
   slice0 := make([]map[string]int,0,10)
   //我们看看打印的东西
   fmt.Println("slice=",slice)
   fmt.Println("slice=0",slice0)


   ///*   先看这段
   //因为有5个长度,所以初始化了5个map,但是map没有通过make申请内容空间,所以报错nil map
   //slice[0]["age"] = 10;//报错
   //下面不报错
   slice[0] = make(map[string]int,10)
   slice[0]["age"] = 19
   fmt.Println(slice[0]["age"])
   //*/
}

 

输出结果:

 

slice= [map[] map[] map[] map[] map[]]

slice=0 []

19

 

接下来继续看代码:

 

package main


import "fmt"


func main() {
   //由map组成的切片
   //第一部分 make[] 声明切片
   //第二部分 map[string]int  声明该切片内部装的单个类型是map
   //第三部分 参数 5 表示该切片的长度和容量都是5
   //长度是用索引能取到第几个元素,索引不能超过长度-1,分配长度后都是默认值,int是0,引用类型是nil
   //append元素到切片时,是添加到最末尾的位置,当元素未超过容量时,都是用的同一个底层数组
   //超过容量时会返回一个新的数组
   //make([]切片类型,切片长度,切片容量)
   //make([]切片类型,切片长度和容量等同)
   slice := make([]map[string]int,5,10)
   slice0 := make([]map[string]int,0,10)
   //我们看看打印的东西
   fmt.Println("slice=",slice)
   fmt.Println("slice=0",slice0)


   /*   先看这段
   //因为有5个长度,所以初始化了5个map,但是map没有通过make申请内容空间,所以报错nil map
   //slice[0]["age"] = 10;//报错
   //下面不报错
   slice[0] = make(map[string]int,10)
   slice[0]["age"] = 19
   fmt.Println(slice[0]["age"])
   */


}

 

输出:

 

panic: assignment to entry in nil map

看下面这个报错:

 

package main


import "fmt"


func main() {
   //由map组成的切片
   //第一部分 make[] 声明切片
   //第二部分 map[string]int  声明该切片内部装的单个类型是map
   //第三部分 参数 5 表示该切片的长度和容量都是5
   //长度是用索引能取到第几个元素,索引不能超过长度-1,分配长度后都是默认值,int是0,引用类型是nil
   //append元素到切片时,是添加到最末尾的位置,当元素未超过容量时,都是用的同一个底层数组
   //超过容量时会返回一个新的数组
   //make([]切片类型,切片长度,切片容量)
   //make([]切片类型,切片长度和容量等同)
   slice := make([]map[string]int,5,10)
   slice0 := make([]map[string]int,0,10)
   //我们看看打印的东西
   fmt.Println("slice=",slice)
   fmt.Println("slice=0",slice0)


   /*   先看这段
   //因为有5个长度,所以初始化了5个map,但是map没有通过make申请内容空间,所以报错nil map
   //slice[0]["age"] = 10;//报错
   //下面不报错
   slice[0] = make(map[string]int,10)
   slice[0]["age"] = 19
   fmt.Println(slice[0]["age"])
   */
   ///*
   //因为初始化了0个长度,所以索引取不到值,报index out of range
   slice0[0]["age"] = 10;


   //*/
}

 

输出:

 

slice= [mappanic: runtime error: index out of range

 

接下来我们看一个:类似于Java中常用的map类型

 

package main


import "fmt"


func main() {
   //类似于Java中的Map<String,HashMap<String,Object>>
   var myMap = make(map[string]map[string]interface{},10)
   fmt.Println(myMap)
   //记得make
   myMap["li_ming_id_123"] = make(map[string]interface{},5)
   myMap["li_ming_id_123"]["school"] = "清华大学"


   fmt.Println(myMap)
}

 

输出:

 

map[]

map[li_ming_id_123:map[school:清华大学]]

 

30.Go中的time时间包模块和Java中的时间API使用区别

 

Go中关于时间处理的操作在time包中  

1.基本获取时间信息  

参考如下代码示例:

package main


import (
   "fmt"
   "time"
)


func main() {
   //获取当前时间
   now := time.Now()
   //获取当前年份
   year := now.Year()
   //获取当前月份
   month := now.Month()
   //获取当前 日期
   day := now.Day()
   //获取当前小时
   hour := now.Hour()
   //获取当前分钟
   min := now.Minute()
   //获取当前秒
   second :=now.Second()


   //获取当前时间戳,和其它编程语言一样,自1970年算起
   timestamp := now.Unix()
   //纳秒时间戳
   ntimestamp := now.UnixNano()




   fmt.Println("year=",year)
   fmt.Println("month=",month)
   fmt.Println("day=",day)
   fmt.Println("hour=",hour)
   fmt.Println("min=",min)
   fmt.Println("second=",second)
   fmt.Println("timestamp=",timestamp)
   fmt.Println("ntimestamp=",ntimestamp)
}

 

2.格式化时间  

Go的时间格式化和其它语言不太一样,它比较特殊,取了go的出生日期作为参数标准  

参考如下代码示例:

package main


import (
   "fmt"
   "time"
)


func main() {
   //获取当前时间
   now := time.Now()


   //2006-01-02 15:04:05这个数值是一个标准写死的,只要改格式符号即可
   fmt.Println(now.Format("2006-01-02 15:04:05"))
   fmt.Println(now.Format("2006/01/02 15:04:05"))
   fmt.Println(now.Format("2006/01/02"))//年月日
   fmt.Println(now.Format("15:04:05"))//时分秒
}