“这是 JavaMemo 的第 4 篇原创。
”
上一节我们彻底搞懂了 Java 中的基础数据类型,本节进一步学习 Java 中的数组。
数组是在几乎所有编程语言都有的数据类型,其本身也是一种数据结构。一说到数组首先就能想到的就是,数组在内存中是一段连续的内存空间,所以我们能通过索引直接访问其中的元素。
这篇文章就把 Java 中数组常用的知识点拿出来一起学习一下,由于面向的是初学者,所以会把一些涉及技术细节的用更适合普通人理解的俗话去演绎,大家搬好小板凳。先来看一下内容大纲。
Java数组零基础入门--大纲在 Java 中数组是相同类型变量的集合,例如, int 数组就是 int 类型变量的集合。数组中的变量是有序的,每个都有一个索引。
单个变量和数组,数组可以保存多个变量数组是相同类型的变量的集合,所有元素的类型都一样
可以指定数组包含的元素个数 ,最多为 int 的最大值个元素
每个元素都有一个固定的编号,称之为索引(index ),从0开始递增,索引类型为 int
可以像操作变量一样读写数组中的任何一个元素,如果说之前的变量是一张有名字的纸,可以通过这个名字读写这个变量;数组则是一个有名字的本子。本子有一个名字,每页纸有一个页码。可以通过本子的名字和页码读写对应的数组元素。
数组是定长的创建之后,长度不可以改变。
创建数组的语法:
元素类型[] 变量名 = new 元素类型[数组长度]
使用数组的语法:
通过:数组变量名[索引],
可以使用这个变量,可以读取也可以给它赋值
下面看一个例子帮助理解数组的这两个基础语法。
public class CreateArray {
public static void main(String[] args) {
int[] intArray = new int[9];
intArray[2] = 16;
System.out.println(intArray[2]);
double[] doubleArray = new double[100];
System.out.println(doubleArray[66]);
// 也可以在创建数组的时候,指定数组包含的所有元素
String[] strArray = new String[]{"one", "two"};
System.out.println(strArray[0]);
}
}
public class ScoreArrayMaxScore {
public static void main(String[] args) {
// 声明六个变量, 分别代表六门科目的成绩
int YuWenIndex = 0;
int ShuXueIndex = 1;
int WaiYuIndex = 2;
int WuLiIndex = 3;
int HuaXueIndex = 4;
int ShengWuIndex = 5;
// 每门课的名字
String[] names = new String[6];
names[YuWenIndex] = "语文";
names[ShuXueIndex] = "数学";
names[WaiYuIndex] = "外语";
names[WuLiIndex] = "物理";
names[HuaXueIndex] = "化学";
names[ShengWuIndex] = "生物";
// 每门课的成绩
double[] scores = new double[6];
// 用随机数给成绩赋值
for (int i = 0; i < 6; i++) {
scores[i] = 80 + Math.random() * 20;
}
// 计算最高成绩和最高成绩对应的科目的索引
double maxScore = -1;
int maxScoreIndex = -1;
for (int i = 0; i < 6; i++) {
System.out.println(names[i] + "的成绩为" + scores[i]);
if (maxScore < scores[i]) {
maxScore = scores[i];
maxScoreIndex = i;
}
}
// 输出最高成绩科目和成绩
System.out.println("最高分的科目为" + names[maxScoreIndex] + ",成绩为:" + maxScore);
}
}
内存就像是有一沓白纸的本子,只能通过页码编号访问,也就是所谓的内存地址。
变量就是使用一个固定的地址加上这个地址对应的内存。计算机通过地址,读写地址对应的内存空间完成变量的赋值和访问的功能。就好像可以根据页码编号,在指定的白纸上写字,或者擦掉再复写。
变量的名就是地址,变量的实就是地址指向的内存里的值。
数组的“实“是一块地址连续的内存,就像是编号连续的一沓白纸。
数组的名,就是这个块连续内存的第一个内存的地址。
数组的变量和基本类型的变量一样,本身代表一个地址。但是与基本变量不一样的是,这个地址的值,是数组的第一个元素所在的内存地址。
通过 数组变量名[索引] 方式访问数组元素的实质,就是在数组原有地址(第一个元素)的基础上,加上索引,获得想要的元素位于内存的地址后进行访问。
数组里的每个元素都有初始值,初始值和元素类型有关,是元素类型的默认值,对于数字类型,初始值就是0,对于boolean类型,初始值是 false。
数组变量的length 属性,可以获取数组的长度。
int[] array = new int[10];
// 通过.length获取数组的长度
system.out.println(array.length);
数组是定长的,创建之后,长度不可以改变。
使用数组常见的一个错误是 IndexOutOfBoundException 数组越界,比如下面就是一个越界的例子
public class IndexOutOfBoundExample {
public static void main(String[] args) {
int[] array = new int[5];
System.out.println(array[array.length]);
}
}
如果没有把握数组是否会越界,可以把索引和数组长度做比较,注意索引是从 0 开始的,不是从 1 开始的。
public class CompareIndex {
public static void main(String[] args) {
int size = 60;
double[] array = new double[size];
for (int i = 0; i < 10; i++) {
int index = (int) (Math.random() * size * 3);
if (index >= 0 && index < array.length) {
System.out.println(array[index]);
} else {
System.out.println("数组出界!");
}
}
}
}
数组变量可以指向新的数组实体。这时候,数组变量的值就是新的数组实体的地址了,这种数组变量的赋值操作,叫做让变量指向新的数组。
public class AssignArray {
public static void main(String[] args) {
int[] array = new int[3];
array[0] = 9;
System.out.println("array长度为" + array.length + "。array[0] = " + array[0] + " array 指向的地址为:" + array);
array = new int[32];
System.out.println("array长度为" + array.length + "。array[0] = " + array[0] + " array 指向的地址为:" + array);
}
}
上面的例程的输出是
array长度为3。array[0] = 9 array 指向的地址为:[I@78e03bb5
array长度为32。array[0] = 0 array 指向的地址为:[I@5e8c92f4
可以看到数组变量指向新数组后,变量值保存的数组地址发生了变化。
如果没有别的数组变量指向原来的数组实体,也就是说,如果没有数组变量“记得”原来数组的地址,原来的数组实体就再也不可访问,也就好像“消失”了。后面会被GC回收。
二维数组是一维数组的延伸。
二维数组定义的语法,比如定义一个doubule类型的二维数组 double[][] = new doube[3][6]
,第一维有三个元素,每个元素的值都是指向的double一维数组的地址,第二维数组的长度为6。
一般写代码时最多就用到二维数组,再多维,写的程序太难让人理解,不推荐使用。
public class MultiDimensionArray {
public static void main(String[] args) {
// 创建一个double类型的二维数组
double[][] multiDimensionArr = new double[3][5];
// 循环查看每个数组元素的值,在给数组元素赋值前,数组元素的值其实都是每种类型的初始值。
for (int i = 0; i < multiDimensionArr.length; i++) {
for (int j = 0; j < multiDimensionArr[i].length; j++) {
System.out.println("multiDimensionArr[" + i + "][" + j + "]=" + multiDimensionArr[i][j]);
}
}
// 其实第一维的数组,每个元素都是一个下一维度的属于的变量。在这里我们可以改变这个变量的值
// 也就是让它指向一个新的变量。
multiDimensionArr[2] = new double[100];
// 检查每个的数组的长度,发现最后一个的长度不一样了,因为它指向了新的数组。
for (int i = 0; i < multiDimensionArr.length; i++) {
System.out.println("multiDimensionArr[" + i + "].length=" + multiDimensionArr[i].length);
}
}
}
import java.util.Scanner;
public class OneArrayForAll {
public static void main(String[] args) {
// 声明六个变量, 分别代表六门科目的成绩
int YuWenIndex = 0;
int ShuXueIndex = 1;
int WaiYuIndex = 2;
int WuLiIndex = 3;
int HuaXueIndex = 4;
int ShengWuIndex = 5;
// 每门课的名字
String[] names = new String[6];
names[YuWenIndex] = "语文";
names[ShuXueIndex] = "数学";
names[WaiYuIndex] = "外语";
names[WuLiIndex] = "物理";
names[HuaXueIndex] = "化学";
names[ShengWuIndex] = "生物";
Scanner scanner = new Scanner(System.in);
System.out.println("请输入共有多少年的成绩:");
int yearCount = scanner.nextInt();
double[][] scores = new double[yearCount][names.length];
for (int i = 0; i < yearCount; i++) {
for (int j = 0; j < names.length; j++) {
scores[i][j] = 80 + Math.random() * 20;
}
}
System.out.println("请问要查看第几年的成绩?");
int yearToUse = scanner.nextInt() - 1;
System.out.println("请问要查看第几科的成绩?");
int scoreToUse = scanner.nextInt() - 1;
System.out.println("第" + (yearToUse + 1) + "年的第" + (scoreToUse + 1) + "门的成绩是:" + scores[yearToUse][+scoreToUse]);
}
}
关于数组方面的基础内容差不多就是这些,学会后,掌握常规的数组使用方法完全不在话下。
其实真正使用 Java 开发程序的时候大部分时候不会直接使用数组,更多会用 ArrayList 这样支持自动扩容和范型的容器,不过它也是在数组的基础上实现的,学知识跟吃饭一样要一口一口啃,等我们把最基础的知识都掌握了后面会有专门的章节学习 ArrayList 这样的容器。
今天仍然是一篇面向零基础人群的内容,如果你工作中需要开始使用 Java,或者身边有刚开始学 Java 的朋友,欢迎把文章分享给他们。