Java中的数组——Java教案(三)

数组

1. 基本概念

  1. 数据是编程语言常见的一种数据结构,可以存储多个数据,每个数组只能存储一种类型的数据,包括元素的赋值和取出数组的元素
  2. Java中,要求数组中的元素有相同的数据类型。因此,数组中的元素类型是唯一的。
  3. 数组一旦初始化完成,数组在内存中所占的空间将会被固定下来,因此,数据的长度将不可改变。
  4. 数组是引用类型,虽然int[] 中int是基本数据类型,但是int[]属于引用数据类型。
  5. 数组是引用数据类型,定义一个变量的时候,仅仅表示了定义了一个引用变量(也就是一个指针),这个变量未指向任何有效的内存,所以还没有内存空间来存储这些元素,这个数据还不能使用,只有初始化后才可以使用。
    1. 定义时,不能指定数组长度
    2. 初始化时,必须指定数组的长度

image-20211117003515614

定义数据的两种方式

int[] arr
int arr []

Java中的数据,必须先进行初始化,然后才可以使用。

2. 初始化的方式

  1. 静态初始化

    1. 使用静态初始化,初始化数组时指定数组元素的初始值不指定数组长度
    //定义一个int数组类型的变量
    //使用静态初始化,初始化数组时指定数组元素的初始值,不指定数组长度
    int[]  arr= {1,2,3,4};
    
    String[] str = {"java","html","css","js"}
    
  2. 动态初始化

    1. arr = new int[length]
    2. length表示数组的长度
    3. 动态初始化时,程序员只需指定数组的长度,即为每个数组元素指定所需的内存空间,系统将负责为这些数组分配初始值。指定初始值时,系统按如下规则
      1. 整形:数组元素的初始值为0
      2. 浮点型,数组元素的初始值为0.0
      3. 字符型,数组元素的初始值为’\u0000’
      4. 布尔型,数组元素的初始值为false
      5. 引用类型(类,接口,数组),数组元素的初始值为null
  3. 注意:

    1. 不要同时使用动态初始化和静态初始化,不要在进行数组初始化时,即指定数组的长度,也为每个有数组元素分配初始值。
    2. 数组初始化完成后,就可以使用数组了,数组的赋值,访问数组元素值和获得数组长度等。

3. 使用数组

静态初始化

int[] arr = {1,2,3,4,5};
//获取数组中的某一个值
System.out.println(arr[4]);
//遍历数组

动态初始化

		//定义一个长度为5的int类型数组
		int[] arr = new int[5];
		// 获取数组中索引为0的元素
		System.out.println(arr[0]);
		// 为数组元素赋值
		arr[0] = 1;
		System.out.println(arr[0]);
		// 获取数组中元素为5的元素
		System.out.println(arr[5]);

注意:

  1. Java语言数组索引是从0开始的,最后一个元素的索引是索引的长度-1
  2. 当访问数组的索引超过数组的长度范围时,会产生数组索引越界的错误
    1. java.lang.ArrayIndexOutOfBoundsException
    2. 这个报错信息是必须要记住的。

遍历数组

  1. for循环

    1. 	//例一:
        		float[] arr = new float[5];
        		arr[0]=0.0f;
        		arr[1]=1.0f;
        		arr[2]=2.0f;
        		arr[3]=3.0f;
        		for (int a = 0; a < arr.length; a++) {
        			System.out.println(arr[a]);
        		}
        
        		//例二:
        		String[] arr = new String[10];
        		arr[0]="java";
        		arr[1]="c++";
        		arr[2]="c#";
        		arr[3]=".net";
        		for(int a =0;a<arr.length;a++) {
        			System.out.println(arr[a]);
        		}
      
  2. foreach循环

    1. 	float[] arr = new float[5];
        		arr[0]=0.0f;
        		arr[1]=1.0f;
        		arr[2]=2.0f;
        		arr[3]=3.0f;
        	    for(float item:arr) {
                	  System.out.println(item);
        	    }
        
        		String[] arr = {"java","c++","c#",".net"};
        	    for(String item:arr) {
        	    	System.out.println(item);
        	    }
      
    2. 相较于for循环

      1. 无需获得数组长度,也无需根据索引来获取数组。
      2. 无需循环条件,无需循环迭代语句。
    3. 注意:使用foreach循环时,不能将数据进行赋值操作。没有意义!

      1. 	String[] arr = {"java","c++","c#",".net"};
          	    for(String item:arr) {
          	    	item = "java";
          	    	System.out.println(item);
          	    }
          	    System.out.println(Arrays.toString(arr));
        
      2. 发现并没有赋值成功。

        1. 原因:foreach的循环变量相当于一个临时变量,系统会把数组依次赋给这个临时变量,而这个临时变量并不是数组元素,它只是保存了数组的值。因此,如果希望改变数组元素的值,不能使用foreach循环。

练习题:

  1. 冒泡排序
  2. 选择排序

4. 深入数组

数组是一种引用数据类型,数组引用变量只是一个引用,数组元素和数组变量在内存里是分开存放的。

内存中的数组

  1. 数组引用变量只是一个引用,这个引用变量可以指向任何有效的内存,只有当该引用指向有效内存后,才可通过该数组变量来访问数组元素。l

  2. 引用变量是访问真是对象的根本方式。

    1. [F@15db9742
      
    2. 数组的地址值,表示真实数组在内存中存储的地址。

    3. image-20211117210722067

  3. 栈和堆

    1. 栈:基本数据类型声明和值,引用类型的声明
    2. 堆:真实对象
    3. 为什么有堆栈之分?
      1. 当一个方法执行时,每个方法都会建立自己的内存栈,在这个方法内定义的变量会逐渐分配到这些内存栈中,随着方法的执行结束,这个方法的内存栈也自然销毁。
      2. 局部变量放在栈内存,当方法结束后,这些局部变量随着栈的销毁而销毁。
      3. 引用类型的变量存储在堆之中,堆内存的对象不会随着方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用。只有当一个对象没有任何引用变量引用时,系统的垃圾回收器才会在合适的时候回收它。
  4. 如何让数组变为垃圾?null

  5. 只要类型相互兼容,就可以让一个数组变量指向另一个实际的数组,这种操作会让人产生数组长度可变的错觉。

    1. 	//展示一:
        		String[] arr = {"java","js"};
        		String[] brr = {"java","js","c#"};
        		System.out.println(Arrays.toString(arr));
        		System.out.println(Arrays.toString(brr));
        		arr=brr;
        		System.out.println(Arrays.toString(arr));
        		//展示二:
        		int[] a = {5,7,20};
        		int[] b = new int[4];
        		b=a;
        		System.out.println(a.length);
      

      image-20211117212705273

    image-20211117212745036

  6. 当执行了b=a会后,堆内存中的第一个数组具有了两个引用;a变量和b变量都引用了第一个数组,第二个数组失去了引用,变成了垃圾,等垃圾回收机制来回收它。

    1.  int[] a = {5,7,10};
          		int[] b = new int[4];
          		b=a;
          		a[0]=100;
          		b[1]=500;
          		System.out.println(Arrays.toString(a));
          		System.out.println(Arrays.toString(b));
      

基本类型数组初始化

基本类型数组,数组元素的值直接存储在对应的数组元素中,因此,初始化数组时,先为该数组分配内存空间,然后直接将数组元素的值存入对应数组元素中。

        //定义一个int[]类型的数组变量	   
		int[] iArr;
		//动态初始化数组,数组长度为5
		iArr=new int[5];
		//采用循环方式为数组元素赋值
		for(int i=0;i<iArr.length;i++) {
			iArr[i]=i+10;
		}
  1. 定义一个数组变量
    1. image-20211117214642378
  2. 动态初始化数组
    1. image-20211117214714177
  3. 为数组元素赋值
    1. image-20211117214747059

引用类型数组初始化

引用类型数组的数组元素是引用,每个数组元素里存储的还是引用,它指向另一块内存,这块内存里存储了有效的数据

public class PersonArray {
	public static void main(String[] args) {
		//定义一个students数组变量,其类型是Person[]
		Person[] students ;
		//动态初始化
		students= new Person[2];
		//创建一个Person实例
		Person zhang = new Person();		
		zhang.age=15;
		zhang.height=158;
		//创建一个Person实例
		Person lee = new Person();
		lee.age=16;
		lee.height=161;
		//为数组中元素赋值
		students[0]=zhang;
		students[1]=lee;
		//执行实例对象的方法
		lee.info();
		students[1].info();
	}
}
class Person {
	public int age;
	public double height;
	public void info() {
		System.out.println("我的年龄是:"+age+"我的身高是:"+height);
	}

}
  1. 定义一个students数组变量,其类型是Person[]

image-20211117220507624

  1. 动态初始化

image-20211117220517242

  1. 创建Person实例

image-20211117220601787

  1. 为数组中元素赋值

image-20211117220540547

  1. 对比数组的赋值,我们将lee赋值给zhang

​ 接上方代码

	   	lee=zhang;
		zhang.age=18;
		System.out.println(zhang.age);
		System.out.println(lee.age);

结果:二者输出一样。

原因:zhang和lee的引用指向同一个对象。

5. 多维数组

Java中提供了支持多维数组的语法,但是Java实际还是没有多维数组的。

原因:

  1. 数组类型是引用类型,因此数组变量是一个引用,这个引用指向真实的数组内存。如果将这个数组元素再次指向真实的数组内存,就看上去像一个多维数组。
  2. 数组类型: type[]。
    1. 定义一个数组,存储int类型的数据:int[]
    2. 定义一个数组,存储Person类型的数据:Person[]
    3. 定义一个数组,存储数组类型的数据:int[] []
public class Array {
	public static void main(String[] args) {
		//定义一个数组类型的数组,即二维数组
		int[][] a;
		//把a当成一个一维数组进行初始化,a是一个长度为4的数组
		a= new int[4][];
		//把a当做一个一位数组进行赋值。
		for(int i=0;i<a.length;i++) {
			System.out.println(a[i]);
		}
		//初始化第一个元素
		a[0]= new int[2];
        //为第一个数组中的第二个元素赋值
		a[0][1]=6;
		for(int i=0;i<a[0].length;i++) {
			System.out.println(a[0][i]);
		}
        
	}

}
  1. 把a当成一个一维数组进行初始化,a是一个长度为4的数组把a当成一个一维数组进行初始化,a是一个长度为4的数组

image-20211117222923184

  1. 为第一个数组中的第二个元素赋值

image-20211117223009938

遍历二维数组

	int[][] arr = new int[5][];
	int[] childOne =new int[4];
	childOne[0]=1;
	childOne[1]=2;
	int[] childTwo = new int[4];
	childTwo[0]=1;
	childTwo[1]=2;
	int[] childThree = {1,2,3};
	arr[0]=childOne;
	arr[1]=childTwo;
	arr[2]=childThree;
//	System.out.println(Arrays.toString(childOne));
//	System.out.println(Arrays.toString(childTwo));
//	System.out.println(Arrays.toString(childThree));
//	System.out.println(arr[0][0]);
//	System.out.println(arr[2][2]);
	for(int a =0;a<arr.length;a++) {
		System.out.println(arr[a]);
		for(int b=0;b<arr[a].length;b++) {
			System.out.println(arr[a][b]);
		}
	}

问题:这样层层嵌套能否实现多维数组呢?

  1. 不能,Java是一个强类型语言,我们定义一个数组 int [ ] [ ] arr 表示我么创建了一个变量,这个变量的类型是数组类型,存储的数据也是数组类型,但是我们数组类型里面要求的是我们存储int类型的数据,因此,我们的二维数组里面就只能存储int类型的数据,不能再存放一个数组。
  2. 如何实现多层数组的存储呢?将数组的存储类型换成Object类型。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

See you !

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

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

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

打赏作者

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

抵扣说明:

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

余额充值