目录
一、数组基础概念
二、数组的声明
1. 基本数据类型数组声明:
2. 引用数据类型数组声明:
三、数组的创建
四、数组的初始化
五、数组的使用
编辑1. 获取长度以及访问元素:
2. 数组作为方法的参数:
3. 数组作为方法的返回值:
六、多维数组
1. 二维数组的声明和初始化
2. 调用数组的指定位置的元素
3. 获取数组的长度
4. 遍历二维数组
5. 二维数组元素的默认初始化值
七、Arrays 类
1. 判断两个数组是否相等
2. 输出数组信息
3. 将指定值填充到数组之中
4. 对数组进行排序
5. 对排序后的数组进行二分法检索指定的值
八、数组的常见应用场景 编辑
一、数组基础概念
数组是同一种类型数据的集合,是一种容器,能给存储进来的元素自动进行编号,编号从 0 开始。数组有以下特点:
长度确定且不可变。一旦数组被初始化,其长度就不能再改变。例如在 Java 中,定义一个整型数组int[] arr = new int[5];,这个数组的长度就是 5,不能在后续的代码中增加或减少这个数组的长度。元素必须是相同类型。Java 中的数组要求数组中的元素类型统一,不能存储不同类型的元素。例如不能在一个整型数组中存储字符串类型的数据。数组变量属引用类型,数组本身也是对象,在堆中分配空间。Java 语言中的数组是一种引用类型,不属于基本数据类型。数组的父类是 Object。数组实际上是一个容器,可以同时容纳多个元素。数组因为是引用类型,所以数组对象是在堆内存当中。数组当中如果存储的是 “Java 对象” 的话,实际上存储的是对象的 “引用(内存地址)”。二、数组的声明
数组在 Java 中有多种声明方式,主要分为基本数据类型数组声明和引用数据类型数组声明。
1. 基本数据类型数组声明:
基本数据类型数组可以使用int[] i或int i[]的方式进行声明。例如,声明一个整型数组可以写为int[] numbers或int numbers[]。Java 中更推荐使用int[] numbers这种方式,因为它具有更好的可读性。
2. 引用数据类型数组声明:
引用数据类型数组可以使用Car[] c或Car c[]的方式进行声明,在 Java 中推荐用Car[] c。比如,如果有一个自定义的类Person,声明一个Person类型的数组可以写为Person[] people。引用数据类型的数组在声明后也需要进行初始化才能使用。初始化的方式可以是静态初始化或动态初始化。例如,静态初始化可以这样写:Person[] people = new Person[]{new Person("张三", 1), new Person("李四", 2)};动态初始化可以这样写:Person[] people = new Person[3],然后再通过给每个元素赋值的方式进行初始化,如people[0] = new Person("王五", 3)。
三、数组的创建
数组在 Java 中有多种创建方式,下面分别介绍基本数据类型数组和引用数据类型数组的创建方法。
创建基本数据类型数组:可以使用int[] i = new int[2];的方式创建一个整型基本数据类型数组。这种方式在创建时指定了数组的长度为 2,创建后数组中的元素会被初始化为对应类型的默认值,对于整型来说,默认值为 0。创建引用数据类型数组:以Car[] c = new Car[100];为例,可以创建一个引用数据类型数组。假设Car是一个自定义的类,这种方式创建了一个长度为 100 的Car类型数组。创建后,数组中的每个元素初始值为 null,因为引用类型的默认值为 null。数组创建后有初始值,数字类型为 0,布尔类型为 false,引用类型为 null。例如,创建一个byte类型的数组,其元素默认初始值是 0;创建一个float类型的数组,其元素默认初始值是 0.0f;创建一个boolean类型的数组,其元素默认初始值是 false;如果创建一个自定义的引用类型数组,如Person[] people = new Person[3],那么创建后数组中的每个元素初始值为 null。四、数组的初始化
数组的初始化方式主要有以下几种:
初始化、创建、和声明分开: 首先进行声明:int[] i; 然后创建数组并指定长度:i = new int[2]; 最后为数组元素赋值:i[0] = 0;,i[1] = 1;。 初始化、创建、和声明在同一时间:可以使用int[] i = {0,1};的方式,直接在声明的同时为数组元素分配空间并赋值。
也可以使用int[] i = new int[]{1,2,3,4,5};的方式,先使用new关键字创建数组,同时为数组中的元素赋值,这里不需要指定数组的长度,数组长度由其后的初始化操作确定。
数组的初始化方式还包括静态初始化、动态初始化和默认初始化。静态初始化是在定义数组的同时为数组元素分配空间并赋值,由系统决定数组的长度,例如int[] a = {1,2,3}或Man[] mans = {new Man(1, 1), new Man(2, 2)}。动态初始化是在初始化时由程序员指定数组的长度,由系统初始化每个数组元素的默认值,例如int[] a1 = new int[2],然后再给数组元素赋值。默认初始化是对于引用类型的数组,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化,例如int a2[] = new int[2],其默认值为0,0;boolean[] b = new boolean[2],其默认值为false,false;String[] s = new String[2],其默认值为null,null。
注意:不要同时使用静态初始化和动态初始化,一旦数组完成初始化,数组在内存中所占的空间将被固定下来,所以数组的长度将不可改变。
五、数组的使用
1. 获取长度以及访问元素:
在 Java 中,获取数组长度非常简单,可以使用arr.length表示获取数组长度。例如:
int[] numbers = {1, 2, 3, 4, 5};int length = numbers.length;System.out.println("数组的长度是: " + length);
访问数组元素可以通过System.out.println(arr[0]);的方式。还可以通过循环语句打印全部元素,如:
for(int i = 0;i < arr.length;i++){ System.out.println(arr[i]);}
此外,还有 for-each 遍历数组语句:for(int i : arr){System.out.println(i);},此方法不可以改变数组的值,只是数组的复制值。
2. 数组作为方法的参数:
可以将数组作为方法的参数来打印数组内容。理解引用类型参数传内置类型时,形参的结果不会影响实参值;参数传数组类型时,在函数内部修改数组内容,函数外部也发生改变。例如:
public static void main(String[] args) { int[] arr = {1, 3, 5}; System.out.println(arr[0]); change(arr); System.out.println(arr[0]);}public static void change(int[] arr) { arr[0] = 200;}
3. 数组作为方法的返回值:
数组也可以作为方法的返回值。比如:
public class Demo02ArrayReturn { public static void main(String[] args) { int[] result = calculate(10, 20, 30); System.out.println("main方法接收到的返回值数组是:"); System.out.println(result); // 地址值 System.out.println("总和:" + result[0]); System.out.println("平均数:" + result[1]); } public static int[] calculate(int a, int b, int c) { int sum = a + b + c; // 总和 int avg = sum / 3; // 平均数 int[] array = {sum, avg}; System.out.println("calculate方法内部数组是:"); System.out.println(array); // 地址值 return array; }}
六、多维数组
1. 二维数组的声明和初始化
Java 中二维数组可以有多种声明和初始化方式,例如: int[][] arr1=new int[][]{{1,2,3},{4,5,6}};:这是一种静态初始化的方式,直接在创建数组的同时为其赋值。 String[][] arr2=new String[3][2];:动态初始化,指定了二维数组的外层长度为 3,内层长度为 2,但未为元素赋值。 String[][] arr3=new String[3][];:动态初始化,只指定了外层长度为 3,内层长度未确定。 int[] arr4[]=new int[][]{{1,2,3},{4,5,6}};:另一种声明方式,与第一种类似,也是静态初始化。 int[] arr5[]={{1,2,3},{4,5,6}};(类型推断):简洁的初始化方式,省略了new关键字,但效果与第一种相同。2. 调用数组的指定位置的元素
二维数组的元素可以通过指定行和列的索引来访问。例如,对于二维数组arr,内层元素可以通过arr[行索引][列索引]来访问,如arr[3][2];外层元素可以通过只指定行索引来访问,如arr[3]。3. 获取数组的长度
在二维数组中,可以使用arr.length来获取外层元素的数量,即数组的行数。而要获取某一行(外层元素)的长度(列数),可以使用arr[行索引].length。例如,如果有一个二维数组int[][] arr = {{1,2,3},{4,5,6}};,那么arr.length的值为 2,arr[0].length的值为 3。4. 遍历二维数组
二维数组可以使用嵌套的for循环来遍历。外层for循环遍历外层元素,控制行数;内层for循环遍历内层元素,控制列数。例如:int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) { System.out.print(arr[i][j] + " "); } System.out.println();}
这段代码会依次输出二维数组中的每一个元素,每输出完一行元素后换行。
5. 二维数组元素的默认初始化值
对于初始化方式int[][] arr = new int[4][3];,外层元素的初始化值为地址值,内层元素的初始化值与一维数组初始化情况相同。例如,对于整型二维数组,内层元素的初始值为 0。 对于初始化方式int[][] arr=new int[4][];,外层元素的初始化值为null,内层元素的初始化值不能调用,否则会报错。例如:int[][] arr = new int[4][];System.out.println(arr[0]); // null// System.out.println(arr[0][0]); // 会报错,空指针异常
七、Arrays 类
Java 中的java.util.Arrays类是操作数组的工具类,包含了用来操作数组的各种方法,如判断两个数组是否相等、输出数组信息、将指定值填充到数组之中、对数组进行排序、对排序后的数组进行二分法检索指定的值。
1. 判断两个数组是否相等
可以使用Arrays.equals(数组1,数组2)方法来判断两个数组是否相等。数组类型必须相等,该方法的返回值为boolean类型。例如:
int[] arr1 = new int[]{1,2,3,4,6};int[] arr2 = new int[]{1,2,3,4,5};boolean isEquals = Arrays.equals(arr1, arr2);System.out.println(isEquals);
2. 输出数组信息
使用Arrays.toString(数组名)方法可以输出数组信息。例如:
int[] arr2 = new int[]{1,2,3,4,5};System.out.println(Arrays.toString(arr2));
3. 将指定值填充到数组之中
Arrays.fill(数组名,填充值)方法可以将指定值填充到数组之中。填充值数据类型应与数组数据类型相同,该方法会把要填充的数组数据全部改为指定值。例如:
int[] arr2 = new int[]{1,2,3,4,5};Arrays.fill(arr2,9);System.out.println(Arrays.toString(arr2));
4. 对数组进行排序
使用Arrays.sort(数组名)方法可以对数组进行排序。例如:
int[] arr2 = new int[]{5,4,1,2,3};Arrays.sort(arr2);System.out.println(Arrays.toString(arr2));
5. 对排序后的数组进行二分法检索指定的值
使用Arrays.binarySearch(数组名,查询值)方法可以对排序后的数组进行二分法检索指定的值。使用前提是当前数组必须是有序的,返回值为int,为负则查找失败,找到了返回下标。例如:
int[] arr1 = new int[]{1,2,3,4,6};int index = Arrays.binarySearch(arr1,1);System.out.println(index);
八、数组的常见应用场景
数组在实际编程中有很多常见的应用场景,其中之一就是存储一组数据进行统计分析,如计算平均值、最大值、最小值等。
例如,可以使用以下方法获取数组中的最大值和最小值:
方法一:该方法使用交换顺序来寻找最大值,但查找完以后会污染数组,不能同时运行寻最大值方法和最小值方法。
/*获取数组里的最大值和最小值*/public class TestFindArrayNum { public static void main(String[] args) { int[] arr = {500,11,12,100,11,13,1,3,5,205,7,9,2,4,6,8,400,0,300,10}; findMaxNum(arr); //使用寻找最小值方法之前要先注释掉寻找最大值的方法 //因为使用完寻找最大值的方法后会污染数组,整个数组都会变为最大值500 //findMinNum(arr); } private static void findMaxNum(int[] arr) { int maxNum = 0; for (int i = 0; i < arr.length - 1; i++) { if (arr[i + 1] > arr[i]) { maxNum = arr[i + 1]; } else { arr[i + 1] = arr[i]; maxNum = arr[i]; } } System.out.println("数组中最大值是" + maxNum); } private static void findMinNum(int[] arr) { int minNum = 0; for (int i = 0; i < arr.length - 1; i++) { if (arr[i + 1] < arr[i]) { minNum = arr[i + 1]; } else { arr[i + 1] = arr[i]; minNum = arr[i]; } } System.out.println("数组中最小值是" + minNum); }}
方法二:方法二代码更加简洁且不会污染数组
/*获取数组里的最大值和最小值*/public class TestFindArrayNum2 { public static void main(String[] args) { int[] arr = {500,11,12,100,11,13,1,3,5,205,7,9,2,4,6,8,400,0,300,10}; findMaxNum(arr); findMinNum(arr); } private static void findMaxNum(int[] arr) { int max = arr[0]; for (int i = 1; i <= arr.length - 1; i++) { if (max < arr[i]) { max = arr[i]; } } System.out.println("数组中最大值" + max); } private static void findMinNum(int[] arr) { int min = arr[0]; for (int i = 1; i <= arr.length - 1; i++) { if (min > arr[i]) { min = arr[i]; } } System.out.println("数组中最小值" + min); }}
方法三:
public class TestFindArrayNum3 { private int max; private int min; public int getMax() { return max; } public int getMin() { return min; } public void FindMaxAndMin(int[] arr ) { if(arr==null){ System.out.println("输入的数组为空"); return; } int i = 0; int len = arr.length; max = arr[0]; min = arr[0]; //两两分组,把较小的数挪到左边,较大的数挪到右边 for(i = 0; i < len - 1; i += 2){ if(arr[i]>arr[i + 1]){ int tmp = arr[i]; arr[i]= arr[i + 1]; arr[i + 1]= tmp; } } //最小值放在各个分组的左边 min = arr[0]; for(i = 2; i < len ; i += 2){ if(arr[i]<min){ min = arr[i]; } } //最大值放在各个分组的右边 max = arr[1]; for(i = 3; i < len; i += 2){ if(arr[i]>max){ max = arr[i]; } } //如果数组中元素个数是奇数个,最后一个元素被分为一组,需要特殊处理 if(len%2==1){ if(max<arr[len - 1]) max = arr[len - 2]; if(min>arr[len - 1]) min = arr[len - 1]; } } public static void main(String[] args) { int[] arr={500,11,12,100,11,13,1,3,5,205,7,9,2,4,6,8,400,0,300,10}; TestFindArrayNum3 f =new TestFindArrayNum3(); f.FindMaxAndMin(arr); System.out.println("最大值是"+f.getMax()); System.out.println("最小值是"+f.getMin()); }}
除了获取最大值和最小值,还可以计算数组的平均值。一般情况下对数组计算均值,可以采用对数组求和,再除以数组长度。实现代码:
public double doubleArrAverage(double[] arr) { double sum = 0; for (int i = 0; i < arr.length; i++) { sum += arr[i]; } return sum / arr.length;}
但其中存在最大问题就是数组求和,如果数组内元素值较大或者数组元素非常多,很有可能出现内存溢出。解决这种问题,一种方法是采用每个元素除以数组长度,再对结果求和。实现代码:
public double doubleArrage(double[] arr) { double result = 0; for (int i = 0; i < arr.length; i++) { result += arr[i] / arr.length; } return result;}
另一种方法是,假定数组长度是动态的,当存在一个元素时,均值ave即为当前数组值arr[0]。当加入第二个个元素,第二个元素减去均值ave,得到的差值除以数组长度,再与均值ave相加,即可得到数组均值。以此类推,直到数组所有元素参与计算,也就完成了整个数组均值计算。实现代码:
public double doubleArrage(double[] arr) { double result = arr[0]; for (int i = 1; i < arr.length; i++) { double temp = arr[i]; result += (temp - result) / (i + 1); } return result;}
在实际编程中,数组还可以用于对用户输入的成绩进行排序和计算平均分。例如:
Scanner scanner = new Scanner(System.in);int[] scores = new int[5];for (int i = 0; i < scores.length; i++) { scores[i] = scanner.nextInt();}Arrays.sort(scores);double average = Arrays.stream(scores).average().orElse(Double.NaN);
这段代码演示了如何使用数组来收集用户输入的成绩,对这些成绩进行排序,并计算平均值。
数组的常见应用场景还包括排序算法教学、搜索引擎索引、股票市场分析等。在排序算法教学中,可以使用数组来展示冒泡排序、选择排序等算法;在搜索引擎索引中,可以使用数组作为倒排索引的一部分,快速检索关键词;在股票市场分析中,可以使用数组存储股票价格,分析市场趋势。