Java学Go入门笔记01-数组
该系列是在有Java基础上学习Go语言的一些基础的对比学习笔记。
数组
数组基础特点回顾:
- 数组是一种线性数据结构。使用一组连续内存空间存储一组相同类型的数据。
- 支持随机访问,按照下标访问数组中的元素的时间复杂度是O(1)。
- 在数组中查找数据,即使是排好序的数组,使用二分查找,时间复杂度也只能达到O(logn)。
- 插入和删除低效,因为需要维持连续的内存空间,在插入时需要在插入位置之后数组数据向后移动。删除时需要将被删位置之后的数据前移。
寻址公式
多维数组,一般先按行,再按列(或者先按列,再按行,这里以 先按行为例)的方式依次存储在连续的存储空间中。后续涉及多维数组时以二维数组为例
- 一维数组:
address_a[i] = base_address + i * data_type_size
- 多维数组:假设二维数组:a[m][n] ,则 a[i][j] 的寻址公式:
addres_a[i][j]=base_address + (i*n+j)*data_type_size
这些是数据结构中的特点,编程语言实际实现可能存在一些不同的地方。比如:
- 编程语言中基础数组实际是不可变的,一旦创建不会再改变数组大小。
- 不同的语言多维数组存储方式不一定都按照上面的寻址公式,可能每一行或者每一列连在一起,但行与行/列与列之间并不相连。
GO中的数组
声明与创建
声明需要指定数组的长度和数组中元素的类型,基础格式是 var arrRefVal [len]dataType
,如声明一个长度为3的int
类型数组 a :var a [3]int
在 GO 语言中,只有数组长度(即最大能存储的元素个数)和元素类型完全相同的才算做同一类型数组,两者缺一都会提示异常。
创建方式(下面示例将创建与声明合并):
// 基础写法
var arrRefVal [len]dataType = [len]dataType{value0, value1, ..., valuek}
// 不指定长度,在编译期间通过源代码推导数组的大小,最终内部自动转换成上面的格式。
// 实质属于语法糖
var arrRefVal [...]dataType = {value0, value1, ..., valuek}
// 语法糖二,通过 `:=` 省去 `var` 关键字,等同于基础写法
arrRefVal :=[len]dataType{value0, value1, ..., valuek}
2
3
4
5
6
7
值复制
Go语言中的数组在赋值和函数调用中的形参都是值传递(Go中均是值传递)。意味着新形参的数组的变更,对源数组无效。
该规则对基础类型数与结构体数组均适用,简单示例:
// 声明并创建一个数组 a1
a1 :=[...]int{1,2,3,6,8}
// 声明一个数组 a2
var a2 [5]int
a2 = a1
// 声明并创建新数组a3
a3 := a1
// 修改a2的值
a2[1] = 5
// 查看三个数组的结果,可以看到:
// 三个数组地址不同
// 数组a2 的修改值后,其余两个不会跟着一起变
fmt.Println(">>>>>>>>>>>>>>WindCoder.com>>>>>>>>>>>>>>")
fmt.Printf("a1值:%v ,a1地址:%p , a1[0]地址:%p\n", a1,&a1,&a1[0])
fmt.Printf("a2值:%v ,a2地址:%p , a2[0]地址:%p\n", a2,&a2,&a2[0])
fmt.Printf("a3值:%v ,a3地址:%p , a3[0]地址:%p\n", a3,&a3,&a3[0])
fmt.Printf(">>>>>>>>>>>>>>WindCoder.com>>>>>>>>>>>>>>")
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Go中存在指针:
&
用于获取指针地址,*
用于获取指针变量的值- Go语言不支持指针运算
内存存储
根据存储内容,大致可分为基础数据类型数组、结构体数组(即引用类型数组)、多维数组。
- 基础数据类型数组中保存的是值
- 引用类型数组中保存的是地址
- 多维数组保存内容与一维数组的方式相同,先行后列依次存储
Java中的数组
声明与创建
声明的基础格式是 dataType[] arrRefVal
或者 dataType arrRelVal[]
,前者是常用格式。
如声明一个整型 int
的数组:int[] arry
。
声明数组,此时不存在初始化,仅在栈中存在变量名。
基础数组创建方式如下:
// 方案一 数组初始化为dataType的默认值
/**
* 声明并初始化
* 一、使用 dataType[arraySize] 创建了一个数组。
* 二、把新创建的数组的引用赋值给变量 arrayRefVar。
**/
dataType[] arrayRefVar = new dataType[arraySize];
arrayRefVar[i] = value0;
// 方案二
dataType[] arrayRefVar = new dataType[]{value0, value1, ..., valuek};
// 方案三 方案二的语法糖,编译器会自动编译成方案二的形式
dataType[] arrayRefVar = {value0, value1, ..., valuek};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
多维数组创建方式
//以二维基础数据类型数组为例,存在如下三种方式
int[ ][ ] arr = new int[3][4];
int[ ][ ] arr = new int[3][ ];
int[][] arr = {{1,2},{3,4,5,6},{7,8,9}};
2
3
4
内存存储
Java 中数组根据存储内容,即dataType,可分为 基本数据类型数组、对象类型数组、多维数组
- 基本数据类型数组:直接存储值
- 对象类型数组:存储对象在内存中的地址
- 多维数组:行内连续,行之间不一定连续
基本数据类型数组 int arr1 = {1,2,3,4}
- arr1 在栈中
- new 申请的空间在堆中,所以数组空间在堆中。
- arr1 中保存的是数组空间的首地址
- 数组空间中保存是基础数据类型
对象类型数组 User[] arr2 = {new User("ZhangSan"),new User("ZhaoSi"), new User("WangWu")}
- 数组中保存的是对象的地址
多维数组:int[][] a3
、User[][] a4
- 内存每一行是连续的,行与行之间不一定连续。
- 内存中保存的内容和一维数组规则相同
除特别注明外,本站所有文章均为 windcoder 原创,转载请注明出处来自: javaxuegorumenbiji01-shuzu

暂无数据