Java:数组部分知识汇总

一、数组定义及初始化

数组这玩意是一种用于存放数据最常见数据结构。

1、数组的的概念及注意点

  • 数组要求所有的数组元素具有相同的数据类型,且只能存在一种数据类型,要多专一有多专一。
  • 数据类型既可以是基本类型也可以是引用类型,类里虽然有不同对象,但都属于同一类,也可存于数组。
  • 数组就是一种引用类型。
  • 数组一旦初始化完成,长度就已经确定,所占内存空间也被固定且不能改变,把数据删除也没用。

2、数组的定义

// 定义数组
char[] initArrays;
char initArrays1[];
  • 两者都可以定义一个数组,但建议使用第一种,也就是type[] arrayname,因为具有较好的可读性,让人一看就知道是个char[]类型的。
  • 仅仅定义了一个引用对象,且并没有指向任何的内存,所以暂时是不能使用的,需要对它初始化

3、数组的初始化

形式

  • 静态初始化
//静态初始化
char[] initArrays0;
initArrays0 = new char[]{'1','2'};
//char[] initArrays0= {'1','2'};

静态初始化需要人为显式指定每个数组元素的初始值,由系统决定数组长度。

type[] arrayname={element1,element2...};是上面两条语句的对于数组静态初始化的简化语法格式。

注意数组元素由花括号扩起,且由逗号分隔。

  • 动态初始化
//动态初始化
int[] arrays;
arrays = new int[3];
//int[] arrays = new int[3];

动态初始化是人为指定数组长度,由系统为数组元素分配初始值。

同样,动态初始化也有简化格式:type []arrayname = new int[length];

注意方括号内需指定数组的长度。

一旦为数组的每个元素数组分配了内存空间,每个内存空间里存储的内容就是该元素的值,即使内容为空,也是null值,所以不论哪种方式初始化数组,都会使数组元素获得初始值。只不过初始值的获得的方式不一样罢了,一个是人给的,一个是系统给的。

动态分配的初始值

既然动态初始化数组只需要指定每个元素所需的内存空间,由系统为各个元素赋初值,那么,这些初值系统又是如何来赋予的呢。以下是对各个不同类型的数组赋初值的尝试:

int[] arrays = new int[3];
boolean[] arrays1 = new boolean[3];
String[] arrays2 = new String[3];
float[] arrays3 = new float[3];
char[] arrays4 = new char[3];
System.out.println(arrays[0]);//0
System.out.println(arrays1[0]);//false
System.out.println(arrays2[0]);//null
System.out.println(arrays3[0]);//0.0
System.out.println(arrays4[0]);//输出'\u0000'为空
}

再根据查找资料,做出总结:

  • 整数类型(byte,short,int,long)->0;
  • 浮点类型(float,double)->0.0;
  • 字符类型(char) ->’\u0000’;
  • 布尔类型(boolean) ->false;
  • 引用类型(类,接口,数组)->null;

小tips:关于输出’\u0000’为空引发的思考:Java 中各种空(""、\u0000、null)的区别?

二、Java数组使用以及foreach循环

1、数组使用

二话不说,先甩一个简单的程序:

final int NUM= 10;
int[] arrays = new int[NUM];
System.out.println(arrays.length);//10
for(int i = 0;i<5;i++){
    arrays[i] = i;//赋值
}
//foreach
for(int element:arrays){
    System.out.print(element+" ");
}
// 0 1 2 3 4 0 0 0 0 0
  • 动态创建一个数组arrays,指定数组长度为10。
  • 索引从0开始,以长度减1结束,越界会报错。
  • length属性可以得到数组的长度,例如arrays.length.
  • 数组名[index]访问数组元素,即可对其进行赋值操作。
  • 由于动态初始化,没有进行赋值的部分为系统默认值0。
  • 输出打印运用了foreach循环,是Java中为数组和集合而生的循环。

2、foreach循环

格式:

for(元素类型 元素:数组名){...}
  • 可以看出,相比for循环,foreach不关心数组的长度,也不需要靠索引值来访问数组元素,而是遍历所有的元素
  • 元素类型和数组类型总该一样吧,不然咋放进去。
  • 书上看到一种说法,让我印象深刻:for each element in array,意思就是数组中的每一个元素。

注意:

int []arrays = {1,2,3,4,5};
// int i;
System.out.println("使数组中每个元素加1");
for(int i:arrays){
    i+=1;
    System.out.print(i+" ");
}
System.out.println();
System.out.println("修改后:");
for(int j:arrays){
    System.out.print(j+" ");
}	
/**
使数组中每个元素加1
2 3 4 5 6
修改后:
1 2 3 4 5*/
  • 在foreach中对数组元素赋值并没有作用。
  • 在进行foreach循环时,其实系统将数组的元素赋给了临时变量,所以并不会改变原来数组。

三、Java数组深入

1、内存中的数组

前边提到:数组是一种引用类型,数组引用变量只是一个引用,当它指向有效内存的时候才可以通过数组变量来访问数组元素,也就是说数组变量和数组元素在内存中是分开放的。

可以这么理解,一个人名就是一个引用变量,通过这个人名找到这个人,获取他的所有信息,就是通过引用变量访问其真实对象的过程。

例如数组int[]arr中arr是一个数组引用变量,但他并没有初始化,也就是说没有指向一块内存,所以它并不能被使用。int[]arr = new int[3]; 而这个语句则明确申请了一块三个int(12个字节)空间的内存,并让arr这个数组引用变量去指向他,以此来访问实际的数组对象。

那么,这两个东西在内存中具体在哪呢?

  • 实际的数组对象被存在堆(heap)内存中。

  • 数组引用变量如果是局部变量,就被存在栈(stack)内存中。

Java中的堆和栈

  • 所有的方法中定义的局部变量都会逐个放入栈内存中,方法结束,栈内存就会销毁。

  • 而每创建一个对象,就会被保存到堆内存中,以便反复利用,即运行时数据区,不会随方法的结束销毁,意味着,方法结束后,还可能有另一个引用变量正在指向它。注意:只有当一个对象没有任何引用变量引用它时,才会变成垃圾,被系统的垃圾回收器自动回收。

所以:想要让一个数组彻底变成“垃圾”,直接将数组变量赋值null。

如下:

int[]arr = new int[3];
arr = null;
arr[1]=0;//java.lang.NullPointerException 

具体关于Java中的垃圾回收机制,以后再具体的进行总结,待补充。。

2、基本类型初始化

前边也提到,数组如果没有进行初始化,是不能够使用它的,那么初始化的过程在内存中又是如何体现的呢,基本类型的初始化和引用类型的初始化又有何不同呢。

对于基本数组而言,数组元素的值直接存储在对应的数组元素中。所以初始化数组时,先为数组分配内存空间,然后直接把数组元素的值放到对应的位置上。

public class Test1
{
    public static void main(String[] args)
    {  
        //定义一个int[]类型的数组变量 
        int[] arr;
        //动态初始化数组,整型默认为0
        arr = new int[4];
        //利用for循环给数组每个元素赋值
        for(int i = 0;i<arr.length;i++) arr[i]=i;
        //打印显示数组结果
        for(int i:arr) System.out.print(i+" ");//0 1 2 3
    }
}
  • 定义数组变量

  • 动态初始化

  • 赋值

3、引用类型数组的初始化

欸,数组本身就是引用类型,创建的数组元素又是引用类型,数组元素还指着另外一块内存,那里才装着有效数据

我们知道,类是引用类型的其中一种,所以下面通过建立一个全是类的数组,关于数组,应该很快就要开始学习并总结啦,所以这块还是先肤浅地谈一谈,有待补充。

class Hero
{
    public int defenseVal;
    public int attackVal;
}

public class Test
{
    public static void main(String[] args)
    {   
        //定义一个students数组变量,其类型是Hero[]
        Hero[] heros;
        //动态初始化
        heros = new Hero[2];
        //创建一个Hero实例,并让Zed变量指向该实例
        Hero Zed = new Hero();
        //为Zed赋攻击力和防御力属性
        Zed.attackVal = 95;
        Zed.defenseVal = 5;
        //让数组的第一个元素指向实例Zed
        heros[0]=Zed;
        //发现Zed和heros[0]指向同一片内存。
        System.out.println(heros[0].attackVal==Zed.attackVal);
    }
}
  • 定义数组变量

  • 动态初始化

  • 创建实例

  • 赋值

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值