- 数组的理解:数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。数组相关概念:
数组名下标元素数组的长度(元素个数) 数组的特点:
数组是有序排序的数组属于引用数据类型的变量数组的元素,既可以是基本数据类型,也可以是引用数据类型创建数组对象会在内存中开辟一整块连续的内存空间数组的长度一旦确定,就不能修改数组可以直接通过下标(或索引)的方式来调用指定位置的元素 数组的分类:
按照维数:一维数组、二维数组…按照元素的数据类型:基本数据类型元素的数组、引用数据类型元素的数组(对象数组)
基本使用
一维数组的声明和初始化调用数组的指定位置的元素获取数组的长度遍历数组数组元素的默认初始化数组的内存解析
public class ArrayTest {
public static void main(String[] args) {
// ① 一维数组的声明和初始化
int num; // 声明
num = 10; // 初始化
int id = 1001; // 声明 + 初始化
int[] ids; // 声明
// 1.1 静态初始化:数组的初始化和数组元素的赋值操作同时进行
ids = new int[]{1001, 1002, 1003, 1004};
// 1.2 动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names = new String[5];
// 也是正确的写法
int[] arr4 = {1, 2, 3, 4};
// 错误的写法
// int[] arr1 = new int[];
// int[] arr2 = new int[5];
// int[] arr3 new int[3]{1,2,3};
// 总结:数组一旦初始化完成,其长度就确定了。
// ② 如何调用数组的指定位置的元素:通过下标的方式调用
// 数组的下标是从 0 开始的,到数组的长度 - 1 结束。
names[0] = "Tom";
names[1] = "Jerry";
names[2] = "Jack";
names[3] = "Rose";
names[4] = "Faker";
// ③ 如何获取数组的长度
// 属性:length
System.out.println(names.length);
// ④ 如何遍历数组
for (int i = 0; i < names.length; i++) {
System.out.println(names[i]);
}
System.out.println(names); // 输出的是数组的地址:[Ljava.lang.String;@1540e19d
// for (String str : names) {
// System.out.println(str);
// }
}
}
public class ArrayTest1 {
public static void main(String[] args) {
// ⑤ 数组元素的默认初始化值
int[] arr = new int[4];
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
System.out.println("****************");
short[] arr1 = new short[4];
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
System.out.println("****************");
float[] arr2 = new float[4];
for (int i = 0; i < arr2.length; i++) {
System.out.println(arr2[i]);
}
System.out.println("****************");
char[] arr3 = new char[4];
for (int i = 0; i < arr3.length; i++) {
System.out.println(arr3[i]);
}
if (arr3[0] == 0){
System.out.println("你好");
}
System.out.println("****************");
boolean[] arr4 = new boolean[4];
System.out.println(arr4[0]);
System.out.println("****************");
String[] arr5 = new String[4];
System.out.println(arr5[0]);
}
}
一维数组的内存解析
注:字符串并不是存储在堆中,上图为了方便演示,才写成 “堆中开辟空间存放字符串”。
一维数组的练习
public class ArrayDemo {
public static void main(String[] args) {
int[] arr = new int[]{8, 2, 1, 0, 3};
int[] index = new int[]{2, 0, 3, 2, 4, 0, 1, 3, 2, 3, 3};
String tel = "";
for (int i = 0; i < index.length; i++) {
tel += arr[index[i]];
}
System.out.println("联系方式:" + tel); // 18013820100
}
}
import java.util.Scanner;
public class ArrayDemo1 {
public static void main(String[] args) {
// 使用 Scanner,获取学生人数
Scanner scanner = new Scanner(System.in);
System.out.println("请输入学生人数:");
int num = scanner.nextInt();
// 创建数组,并输入学生成绩,动态初始化
int[] scores = new int[num];
System.out.println("请依次输入学生成绩");
int maxScore = 0;
for (int i = 0; i < scores.length; i++) {
scores[i] = scanner.nextInt();
// 获取数组中的元素的最大值:最高分
if (maxScore <= scores[i]) {
maxScore = scores[i];
}
}
// for (int i = 0; i < scores.length; i++) {
// if (maxScore <= scores[i]) {
// maxScore = scores[i];
// }
// }
System.out.println("最高分是:" + maxScore);
// 根据每个学生成绩与最高分的差值,输出学生成绩及等级
for (int i = 0; i < scores.length; i++) {
char level = 'D';
if (scores[i] >= maxScore - 10){
level = 'A';
}else if (scores[i] >= maxScore - 20){
level = 'B';
}else if (scores[i] >= maxScore - 30){
level = 'C';
}
System.out.println("student " + i + " score is " + scores[i] + " level is " + level);
}
}
}
多维数组
基本使用
二维数组的声明和初始化调用数组的指定位置的元素获取数组的长度遍历数组数组元素的默认初始化数组的内存解析
public class ArrayTes2 {
public static void main(String[] args) {
// ① 二维数组的声明和初始化
int[] arr = new int[]{1, 2, 3}; // 一维数组静态初始化
// 二维数组的静态初始化
int[][] arr1 = new int[][]{{1, 2, 3}, {4, 5}, {6, 7, 8}};
// 二维数组的动态初始化_1
String[][] arr2 = new String[3][2];
// 二维数组的动态初始化_2
String[][] arr3 = new String[3][];
// 错误的情况
// String[][] arr4 = new String[][4];
// String[4][3] arr5 = new String[][];
// int[][] arr6 = new int[4][3]{{1,2,3},{4,5},{6,7,8}};
// 正确的情况
int[] arr4[] = new int[][]{{1, 2, 3}, {4, 5, 9, 10}, {6, 7, 8}};
int[] arr5[] = {{1, 2, 3}, {4, 5}, {6, 7, 8}};
// ② 如何调用数组的指定位置的元素
System.out.println(arr1[0][1]);
System.out.println(arr2[1][1]); // null
System.out.println(arr2[1]); // 存放的是地址:[Ljava.lang.String;@1540e19d
// System.out.println(arr3[1][0]); // 空指针异常:NullPointerException
arr3[1] = new String[4];
System.out.println(arr3[1][0]); // null
// ③ 如何获取数组的长度
System.out.println(arr4.length); // 3
System.out.println(arr4[0].length); // 3
System.out.println(arr4[1].length); // 4
// ④ 如何遍历数组
for (int i = 0; i < arr4.length; i++) {
for (int j = 0; j < arr4[i].length; j++) {
System.out.print(arr4[i][j] + " ");
}
System.out.println();
}
}
}
public class ArrayTes3 {
public static void main(String[] args) {
int[][] arr = new int[4][3];
System.out.println(arr[0]); // [I@1540e19d
System.out.println(arr[0][0]); // 0
System.out.println("*****************");
float[][] arr1 = new float[4][3];
System.out.println(arr1[0]); // [F@677327b6
System.out.println(arr1[0][0]); // 0.0
System.out.println("*****************");
String[][] arr2 = new String[4][2];
System.out.println(arr2[1]); // [Ljava.lang.String;@14ae5a5
System.out.println(arr2[1][1]); // null
System.out.println("*****************");
double[][] arr3 = new double[4][];
System.out.println(arr3[1]); // null
System.out.println(arr3[1][0]); // 报空指针异常:NullPointerException
}
}
二维数组的内存解析
二维数组的练习
public class ArrayExer1 {
public static void main(String[] args) {
// 初始化二维数组
int[][] arr = new int[3][];
arr[0] = new int[]{3, 5, 8};
arr[1] = new int[]{12, 9};
arr[2] = new int[]{7, 0, 6, 4};
// 对二维数组的每一项进行求和
int sum = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
sum += arr[i][j];
}
}
System.out.println("arr 数组中所有元素的和为:" + sum);
}
}
public class YangHuiTest {
public static void main(String[] args) {
// 1. 声明并初始化二维数组
int[][] yangHui = new int[10][];
// 2. 给元素赋值
for (int i = 0; i < yangHui.length; i++) {
// 第 n 行有 n 个元素
yangHui[i] = new int[i + 1];
// 第一列以及最后一列的值为 1
yangHui[i][0] = yangHui[i][i] = 1;
// 对其他位置进行赋值
for (int j = 1; j < yangHui[i].length - 1; j++) {
yangHui[i][j] = yangHui[i - 1][j] + yangHui[i - 1][j - 1];
}
}
// 3. 遍历杨辉三角数组
for (int i = 0; i < yangHui.length; i++) {
for (int j = 0; j < yangHui[i].length; j++) {
System.out.print(yangHui[i][j] + " ");
}
System.out.println();
}
}
}
运行结果:
数组中涉及的常见算法分类
数组元素的赋值(杨辉三角、回环数)求数值型数组中的最大值、最小值、平均数、总和等数组的复制、反转、查找(线性查找、二分查找)数组元素的排序算法 求数值型数组中的最大值、最小值、平均数、总和等
public class ArrayTest1 {
public static void main(String[] args) {
// 数组的初始化
int[] arr = new int[10];
for (int i = 0; i < arr.length; i++) {
// 获取两位数的随机数 --> [10,99]
arr[i] = (int)(Math.random() * 90 + 10); // [0,1) -> [0-90) -> [10,100)
}
// 遍历数组
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
// 求数组元素的最大值
int maxValue = arr[0];
for (int i = 1; i < arr.length; i++) {
if (maxValue <= arr[i]){
maxValue = arr[i];
}
}
System.out.println("最大值为:" + maxValue);
// 求数组元素的最小值
int minValue = arr[0];
for (int i = 1; i < arr.length; i++) {
if (minValue > arr[i]){
minValue = arr[i];
}
}
System.out.println("最小值为:" + minValue);
// 求数组元素的总和
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
System.out.println("总和为:" + sum);
// 求数组元素的平均数
int avgValue = sum / arr.length;
System.out.println("平均数为:" + avgValue);
}
}
数组的复制
public class ArrayExer2 {
public static void main(String[] args) {
int[] array1, array2;
array1 = new int[]{2, 3, 5, 7, 11, 13, 17, 19};
// 显示 array1 的内容
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + " ");
}
// 赋值array2变量等于array1
// 不能称作数组的复制。
// array2 = array1; // array1 和 array2 指向同一个数组的地址
// 数组的每一项都进行复制
array2 = new int[array1.length];
for (int i = 0; i < array2.length; i++) {
array2[i] = array1[i];
}
// 修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)
for (int i = 0; i < array2.length; i++) {
if (i % 2 == 0){
array2[i] = i;
}
}
System.out.println();
// 显示 array1 的内容
for (int i = 0; i < array1.length; i++) {
System.out.print(array1[i] + " ");
}
}
}
运行结果:
内存分析:
总结:直接赋值不能实现数组复制,可以使用 for 循环遍历依次赋值。
数组的反转、查找
public class ArrayTest2 {
public static void main(String[] args) {
String[] arr = new String[]{"JJ", "AA", "BB", "DD", "MM", "GG"};
// 数组的复制(区别于数组变量的赋值: arr1 = arr
String[] arr1 = new String[arr.length];
for (int i = 0; i < arr1.length; i++) {
arr1[i] = arr[i];
}
// 数组的反转
// 方式一:
// for (int i = 0, j = arr.length - 1; i < j; i++,j--) {
// String temp = arr[i];
// arr[i] = arr[j];
// arr[j] = temp;
// }
// 方式二:
for (int i = 0; i < arr.length / 2; i++) {
String temp = arr[i];
arr[i] = arr1[arr.length - i - 1];
arr[arr1.length - i - 1] = temp;
}
// 数组的显示
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
// 查找(或搜索)
// 线性查找
String dest = "BB";
dest = "CC";
boolean isFind = false;
for (int i = 0; i < arr1.length; i++) {
if (dest.equals(arr1[i])){
isFind = true;
System.out.println("找到了指定的元素,位置为:" + i);
break;
}
}
if (isFind == false){
System.out.println("很遗憾,没有找到的啦!");
}
// 二分法查找
// 前提:所要查找的数组必须有序。
int[] arr2 = new int[]{-98,-34,2,34,54,66,79,105,210,333};
int dest1 = -34;
int start = 0;
int end = arr2.length;
boolean isFind1 = true;
while (isFind1){
int mid = (start + end) / 2;
if (dest1 == arr2[mid]){
System.out.println("找到了指定的元素,位置为:" + mid);
isFind1 = false;
break;
}else if (dest1 > arr2[mid]){
start = mid + 1;
}else {
end = mid - 1;
}
}
if (isFind1){
System.out.println("很遗憾,没有找到的啦!");
}
}
}
排序算法(冒泡排序)
思路:
从头开始比较相邻的两个变量大小,每次循环结束都会将最大的一个数移动到最后数组元素个数为 n,需要循环 n-1 次。 动态图
代码如下:
public class BubbleSortTest {
public static void main(String[] args) {
int[] arr = new int[]{43,32,76,-98,0,64,33,-21,32,99};
// 冒泡排序:比较相邻两个元素的大小,进行交换
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] >= arr[j + 1]){ // 交换变量
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
Arrays 工具类
基本使用
import java.util.Arrays;
public class ArraysTest {
public static void main(String[] args) {
// 1.boolean equals(int[] a,int[] b):判断两个数组是否相等。
int[] arr1 = new int[]{1,2,3,4};
int[] arr2 = new int[]{1,3,2,4};
boolean equals = Arrays.equals(arr1, arr2);
System.out.println(equals);
// 2.String toString(int[] a):输出数组信息。
System.out.println(Arrays.toString(arr1));
// 3.void fill(int[] a,int val):将指定值填充到数组之中。
int num = 5;
Arrays.fill(arr1, num);
System.out.println(Arrays.toString(arr1));
// 4.void sort(int[] a):对数组进行排序。
Arrays.sort(arr2);
System.out.println(Arrays.toString(arr2));
// 5.int binarySearch(int[] a,int key):二分查找,数组必须有序
int[] arr3 = new int[]{-98,-34,2,34,54,66,79,105,210,333};
int index = Arrays.binarySearch(arr3, 34);
if (index >= 0){
System.out.println("找到了");
}else {
System.out.println("没有找到");
}
}
}
运行结果
数组常见异常数组下标越界异常(ArrayIndexOutOfBoundsExcetion)
public class ArrayExceptionTest {
public static void main(String[] args) {
// 数组角标越界的异常:ArrayIndexOutOfBoundsExcetion
int[] arr = new int[]{1,2,3,4,5};
for(int i = 0;i <= arr.length;i++){
System.out.println(arr[i]);
}
System.out.println(arr[-2]);
System.out.println("hello");
}
}
空指针异常(NullPointerException)
public class ArrayExceptionTest {
public static void main(String[] args) {
// 空指针异常:NullPointerException
// 情况一:
int[] arr1 = new int[]{1,2,3};
arr1 = null;
System.out.println(arr1[0]);
// 情况二:
int[][] arr2 = new int[4][];
System.out.println(arr2[0][0]);
// 情况三:
String[] arr3 = new String[]{"AA","BB","CC"};
arr3[0] = null;
System.out.println(arr3[0].toString());
}
}



