java学习笔记(九)一维数组与内存关系

目录

1.一维数组含义:

2.数组作用:

3.数组的声明:

4.数组的初始化

1.静态初始化:

2.动态初始化:

内存:

 步骤:

静态初始化内存:

我们来看看动态初始化

5.数组的使用:

1.通过下标获取元素

2.获取数组中元素个数

3.遍历数组

4.增强for循环遍历数组

注意:

 6.数组的复制

 数组复制内存图​

我们来看看复制时候的内存图 

7.数组的扩容

8.数组的删除


今天来学习一维数组,并深入底层理解一维数组。

1.一维数组含义:

一组数组的容器

2.数组作用:

存放数据,并且操作数据

3.数组的声明:

1.数据类型[] 数组名;

2.数据类型 数组名[];

4.数组的初始化

1.静态初始化:

我们来指定元素,系统自动分配空间长度

比如:

String[] names = new String[]{"张三","李四","王五","小红","小绿"};
String[] names;
names = new String[]{"张三","李四","王五","小红","小绿"};
String[] names = {"张三","李四","王五","小红","小绿"};

三种静态初始化最后的结果是一样的。

2.动态初始化:

我们来指定长度,系统会自动分配元素

在系统自动分配的时候,系统会自动把数组中元素置为空(null),我们来总结一下系统会自动默认分配的类型:

整数类型:0

浮点类型:0.0

字符类型:'  '

布尔类型:false

引用类型:null

我们声明的数组就是引用类型,所以系统会自动把数组元素置为空

比如:

String[] names = new String[5]

//通过下标设置元素
names[0] = "张三";
names[1] = "李四";
names[2] = "王五";
names[3] = "小红";
names[4] = "小绿";

内存:

(主要以jdk1.7为例子)

 步骤:

1.jvm会将这个类加入到方法区,存放字节码类文件

2.扫描整个程序,找到所有的字面值常量(数字,字符串等),和final修饰的变量

3.一旦调用方法,就会在栈里面开辟方法,用于存放改方法内的局部变量,一旦方法执行完毕,垃圾回收器(gc)会立刻回收

4.在堆里面开辟空间,存放new出来的对象,用于存放对象中数据

静态初始化内存:

就比如我们在main方法中声明一个数组,采用静态初始化的方法

1.首先jvm将字节码文件加载到方法区中

2.扫描程序中所有常量,将常量存入常量池

3.调用main方法,在栈中开辟空间,将name这个数组引用赋值给names

4.将常量池里的数据放入对应的区域

 这样就完成了一个数组的初始化(静态初始化)

我们来看看动态初始化

 在刚把names对象创建出来时,系统会自动把全部元素置为空,然后再将常量池中的数据赋值给元素。

注意:

1.数组是引用数据类型
2.new表示新建对象,会在堆内存开辟空间
3.数组一旦初始化后,长度不可改变(数组不可以扩容和删除)
4.数组初始化开辟的空间在内存中是连续的

5.数组的使用:

1.通过下标获取元素

String n = names[2];
System.out.println("通过下标获取元素:" + n);

2.获取数组中元素个数

int len = names.length;
System.out.println("获取数组中元素的个数:" + len);

3.遍历数组

for(int i = 0;i<names.length;i++){
	System.out.println(names[i]);
}

4.增强for循环遍历数组

for(String item : names){//遍历names数组,依次取出元素赋值给item
	System.out.println(element);
}

注意:

下标为负数或者大于等于长度会出现"数组下标越界异常"-ArrayIndexOutOfBoundsException

 6.数组的复制

public class Test{
	
	public static void main(String[] args){
		//原数组
		String[] names = {"张三","李四","王五"};

		String[] newNames = names;
		
		names[1] = "徐精华";
	
		for(String element : newNames){
			System.out.println(element);
		}
	}
}

这段代码就是将原数组赋值给新数组,但是我们会发现,我们改变新数组的元素,原数组的元素也会跟着改变,原因是

将原数组中的对象地址赋值给新数组这个引用,names和newNames这两个引用是指向的同一个数组对象

 数组复制内存图

 此时我们可以看见,两个数组的引用都是同一个数组,所以我们无论改变哪一个数组的元素,两个数组的元素都会跟着改变。

为了能够将数组完全复制出来且不受影响,所以我们采用这种方法,我们用动态初始化再声明一个数组,然后将原数组的元素赋值给新数组。

public class Test{
	
	public static void main(String[] args){

		//原数组
		String[] names = {"麻生希","椎名空","水菜丽","爱田奈奈"};
		
		//新数组
		String[] newNames = new String[names.length];
		
		//遍历原数组,将原数组中的数据依次迁移到新数组中
		for(int i = 0;i<names.length;i++){
			newNames[i] = names[i];
		}
		
		//遍历新数组
		for(String element : newNames){
			System.out.println(element);
		}
	}
}

我们来看看复制时候的内存图 

 可以看到,因为两个数组的引用不一样,现在修改就不会相互影响了。

7.数组的扩容

其实数组是不可以扩容的,所以我们只能换一种方式来,我们可以动态声明一个比较长的数组,然后把原来的数组的元素迁移过去,再将新数组的引用赋值给原来的数组,通过这样来达到扩容的目的。

public class Test08{
	
	public static void main(String[] args){

		//原数组
		String[] names = {"张三","李四","王五"};
		
		//创建新数组(新数组长度是原数组长度的1.5倍)
		int capacity = names.length;
		int newCapacity = capacity*2;
		String[] newNames = new String[newCapacity];
		
		//将原数组的数据迁移到新数组中
		for(int i = 0;i<names.length;i++){
			newNames[i] = names[i];
		}
		
		//将新数组赋值给原数组
		names = newNames;
		
		//遍历原数组
		for(String element : names){
			System.out.println(element);
		}
		
	}
}

8.数组的删除

因为数组的大小是不可以改变的,所以我们可以声明一个新数组,然后将除了删除的那个元素外,将其他元素迁移到新数组,以此达到删除的目的,但是还有一种方法,就是我们用覆盖的方法,将要删除的元素用后面的元素覆盖掉,相当于所有元素往前移动。

public class Test{
	
	public static void main(String[] args){

		//原数组
		String[] names = {"张三","李四","王五"};
		
		//数据的迁移
		for(int i = 1;i<names.length-1;i++){
			names[i] = names[i+1];
		}
		names[names.length-1] = null;
		
		//遍历原数组
		for(String element : names){
			System.out.println(element);
		}
		
	}
}

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yyyiwy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值