Day05_数组

一. 数组的概念

为什么使用数组?

如何存储100名学生的成绩?如何让100名学生成绩全部+1?更复杂的操作呢?

数组可以减少重复操作,并进行统一操作。

概念:

一组连续的存储空间,存储多个相同数据类型的值。

特点:

类型相同,长度固定

二. 数组的声明与赋值

public static void main(String[] args) {
    int[] a = new int[5];
    // int a[] = new int[5]; 也可以
}

int[] a —— 声明int数组类型变量定义变量名为a

new int[5] —— 分配长度为5的连续空间

内存 :

a └─┘└─┘└─┘└─┘└─┘ 可以存储5个int类型的值

数组创建语法:

  • 先声明,再分配空间:
  数组类型[] 数组名;

  数组名 = new 数组类型[长度];
  • 声明并分配空间:
  数组类型[] 数组名 = new 数组类型[长度];
  • 声明并赋值(繁):
  数组类型[] 数组名 = new 数组类型[]{value1,value2,value3,...};
  • 声明并赋值(简):
  数组类型[] 数组名 = {value1,value2,value3,...};

【注】:规范命名:变量名+Array,如iArray

三. 数组的组成

数组中的每个数据格被称为数组元素

对每个元素进行赋值或取值的操作被称为元素的访问

访问元素时,需要使用下标/索引。从0开始,依次+1,自动生成。

访问的语法:

  数组名[索引]

// 如:

存:a[0] = 10;

取:a[0];

数组的使用:

public static void main(string[] args){
    int[] a = new int[5]; // 创建数组
    a[0] = 5;			  // 依次赋值
    a[1] = 3;
    a[2] = 4;
    a[3] = 7;
    a[4] = 10;
    System.out.println(a[0]); // 依次取值
    System.out.println(a[1]);
    System.out.println(a[2]);
    System.out.println(a[3]);
    System.out.println(a[4]);
}

运行结果:

5
3
4
7
10

索引有效范围:0~len-1

访问无效下标,会导致数组索引越界

	System.out.println(a[5]);

Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException : 5

四. 数组的遍历

遍历

从头到尾,对数组的每个元素逐一进行访问。

public static void main(string[] args){
    int[] a = new int[5];
    for (int i = 0; i < a.length; i++) { // 数组名.length 可动态获得数组长度
        System.out.println(a[i]); // 使用循环变量"i"充当下标,从而达到遍历目的
    }
}

【注】:在没有为数组元素赋值的情况下,依旧可以正确进行访问

运行结果:

0
0
0
0
0

数组默认值

整数:0

小数:0.0

字符:\u0000

布尔:false

其他:null

【例】:

给定一个整数数组,统计数组中所有元素的平均值。

读入一个整数n,如果n在数组中存在,输出下标,不存在则输出-1。

import java.util.Scanner;

public class ArrayTest {

	public static void main(String[] args) {
		System.out.println("数组长度:");
		Scanner input = new Scanner(System.in);
		int len = input.nextInt();
		int[] aArray = new int[len];
		System.out.println("数组元素:");
		for (int i = 0; i < aArray.length; i++) {
			aArray[i] = input.nextInt();
		}
		System.out.println("平均值:");
		System.out.println(ave(aArray));
		System.out.println("查找:");
		int search = input.nextInt();
		System.out.println(find(search, aArray));
	}
	
	public static Double ave(int[] a) {
		int sum = 0;
		for (int i = 0; i < a.length; i++) {
			sum += a[i];
		}
		double ave = sum / a.length;
		return ave;
	}	
	
	public static int find(int ele,int[] a) {
		for (int i = 0; i < a.length; i++) {
			if (a[i] == ele) {
				return i;
			} 
		}
		return -1;
	}
	
}

数组的扩容

创建数组时,必须显示指定长度,并在创建之后不可更改长度。

扩容思路
  • 创建大于原数组长度的新数组。
  • 将原数组中的元素依次复制到新数组中。
    在这里插入图片描述
复制的方式
  • 循环将原数组中所有元素逐一赋值给新数组。
  • System.arraycopy(原数组, 原数组起始, 新数组, 新数组起始, 长度);
  • java.util.Arrays.copyOf(原数组, 新长度);// 返回带有原值的新数组

地址的替换

数组作为引用类型之一,其变量中存储的是数组的地址。

完成元素复制后,需将新数组地址,赋值给原变量进行替换。
在这里插入图片描述

数组类型的参数

public class Test {
    public static void main(String[] args) {
        int[] nums = {1, 2, 3, 4};
        printArray(nums);
    }
    
    public static void printArray(int[] oneArray) {
        for (int i = 0; i < oneArray.length; i++) {
            System.out.println(oneArray[i]);
        }
    }
}

运行结果:

1
2
3
4

方法调用时,将nums中的地址赋值给oneArray,此时二者指向同一个数组。

传递参数时:基本类型传递的是变量中的值;引用类型传递的是变量中的地址。

public class ArrayCopyTest {

	public static void main(String[] args) {
		int[] iArray = {1, 2, 3, 4, 5};
		int[] jArray = expandArray(iArray, 4);
		for (int i = 0; i < jArray.length; i++) {
			System.out.println(jArray[i]);
		}
	}
	
	public static int[] expandArray(int[] oldArray, int add) { // (原数组,扩展长度)
		int[] newArray = new int[oldArray.length + add];
		for (int i = 0; i < oldArray.length; i++) {
			newArray[i] = oldArray[i];
		}
		return newArray; // 返回newArray
	}

}

【注】:调用返回类型为数组的方法时,方法执行后,返回的是数组的地址。

可变长参数

概念:可接收多个同类型实参,个数不限,使用方式与数组相同。

语法

数据类型... 形参名// 必须定义在形参列表的最后,且只能有一个。

【注】:必须定义在形参列表的最后,且只能有一个

public class ArrayParameterTest {
    public static void main(String[] args) {
        printArray(1,2,3,4);
    }
    
    public static void printArray(int... oneArray) {	// 定义int型可变长参数
        for (int i = 0; i < oneArray.length; i++) {
            System.out.println(oneArray[i]);
        }
    }
}

运行结果:

1
2
3
4

五. 数组的排序

冒泡排序:相邻的两个数值比较大小,互换位置。

选择排序:固定值与其他值依次比较大小,互换位置。

JDK排序:java.utilArrays.sort(数组名);// JDK 提供(升序)

六. 二维数组

二维数组创建语法:

【注】:[行] [列]

  • 先声明、再分配空间
  数据类型[] []  数组名;

  数组名 = new  数据类型[高维长度] [低维长度];
  • 声明并分配空间
  数据类型[] [] 数组名 = new 数据类型[高维长度] [低维长度];
  • 声明并赋值(繁)
  数据类型[] [] 数组名 = new 数据类型[高维长度] []; // 不规则数组,自行new低维数组
  • 声明并赋值(简)
  数据类型[] [] 数组名 = { { v1, v2, v3 }, { v4, v5 }, { v6, v7, v8, v9 } }; 显式初始化

二维数组的访问:

public class Test2DArray {

	public static void main(String[] args) {
		int iArray[][] = new int[2][3];
		iArray[0][0] = 1;
		iArray[0][1] = 2;
		iArray[0][2] = 3;
		iArray[1][0] = 4;
		iArray[1][1] = 5;
		iArray[1][2] = 6;
		for (int i = 0; i < iArray.length; i++) {
			for (int j = 0; j < iArray[i].length; j++) { // 访问低维长度
				System.out.print(iArray[i][j]+" "); // 访问低维数组元素
			}
			System.out.println();
		}
	}
}

逻辑上:
在这里插入图片描述
内存分配:
在这里插入图片描述
【注】: 高维数组中的每一个元素,都保存了低维数组的地址。访问array[0]等价于在访问0x0000A111

【例】:

杨辉三角

import java.util.Scanner;

public class PascalTriangleTest {

	public static void main(String[] args) {
		System.out.println("打印行数:");
		Scanner input = new Scanner(System.in);
		int r = input.nextInt();

		printArray(PascalTriangle(r), r);
	}

	public static int[][] PascalTriangle(int n) {
		int a[][] = new int[n][n];

		for (int i = 0; i < a.length; i++) {
			a[i][0] = 1;
			a[i][i] = 1;
			for (int j = 1; j < i; j++) {
				a[i][j] = a[i - 1][j - 1] + a[i - 1][j];
			}
		}
		return a;
	}

	public static void printArray(int[][] a, int n) {
		for (int i = 0; i < a.length; i++) {
			for (int j = 0; j < n - i; j++) {
				System.out.print("  ");
			}
			for (int j = 0; j <= i; j++) {
				System.out.printf("%4d", a[i][j]);
			}
			System.out.println();
		}
	}

}

输入:

6

运行结果:

​ 1
​ 1 1
​ 1 2 1
​ 1 3 3 1
​ 1 4 6 4 1
​ 1 5 10 10 5 1

©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页