如何从零基础开始学习Java中的数组操作?

2026-04-11 06:091阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计3314个文字,预计阅读时间需要14分钟。

如何从零基础开始学习Java中的数组操作?

数组+数组存储相同类型值的序列。+声明数组+数组是一种数据结构,用于存储同一类型值的集合。+通过一个整型下标(index)或索引(index)可以访问数组中的每个值。例如,如果a是一个整型数组,则可以访问数组中的每个值。

数组

数组存储相同类型值的序列。

声明数组

数组是一种数据结构,用来存储同一类型值的集合。通过一个整型下标(index,或称索引)可以访问数组中的每一个值。例如,如果a是一个整型数组,a[i]就是数组中下标为i的整数。
在声明数组变量时,需要指出数组类型(数据元素类型紧跟[])和数组变量的名字。下面声明了整型数组a:

int[] a;

不过,这条语句只声明了变量a,并没有将a初始化为一个真正的数组。应该使用new操作符创建数组

int[] a = new int[100];

这条语句声明并初始化了一个可以存储100个整数的数组。
数组长度不要求是常量:new int[n]会创建一个长度为n的数组。
一旦创建了数组,就不能再改变它的长度。如果程序运行中需要经常扩展数组的大小,就应该使用另一种数据结构---数组列表(array list)

在Java中,提供了一种创建数组对象并同时提供初始值的简写形式。如下:

int[] a = {2, 3, 5, 7, 11, 13};

请注意,这个语法不需要使用new,甚至不用指定长度。
最后一个值后面允许有逗号,如果你要不断为数组增加值,这会很方便:

String[] authors = {"James", "Kobe", "Curry", "Durant",};

当然,我们也可以声明一个匿名数组;

new int[] {17, 19, 23, 29, 31, 37}

这会分配一个新数组并填入大括号中提供的值。它会统计初始值的个数,并相应地设置数组大小。可以使用这种语法重新初始化一个数组而无须创建新变量。例如:

smallPrimes = new int [] {17, 19, 23, 29, 31, 37};


注意
在Java中,允许有长度为0的数组。在编写一个结果为数组的方发时,如果碰巧结果为空,这样一个长度为0的数组就很有用。可以如下创建长度为0的数组:

new elementType[0]; 或 new elementType2[] {};

访问数组

前面的数组元素的下标为从0~99(不是1~100)。一旦创建了数组,就可以在数组中填入元素,例如,使用一个循环:

int[] a = new int[100]; for (int i = 0; i < 100; i++) { a[i] = i; }

创建一个数字数组时,所有元素都初始化为0,boolean数组的元素会初始化为false。对象数组的元素则初始化为一个特殊值null,表示这些元素还未存放任何对象。刚开始我们可能有些不了解,例如:

String[] names = new String[10];

我们会创建一个包含10个字符串的数组,所有字符串都为null。如果希望这个数组包含空串,必须为元素指定空串:

for (int i=0; i < 10; i++) names[i] = "";

注意:如果创建了一个100个元素的数组,并且试图访问元素a[100](或在0~99之间的任何下标),就会引发array index out of bounds异常。
如果我们想获得数组中的元素个数,可以使用array.length。例如:

for (int i=0; i<a.length; i++) { System.out.println(a[i]); }

for each循环

Java有一种功能很强的循环结构,可以用来依次处理数组(或者其他元素集合)中的每个元素,而不必考虑指定下标值。这种增强的for循环的语句格式为:

for (variable: collection) statement

它定义一个变量用于暂存集合中的每一个元素,并执行相应的语句(当然,也可以是语句块)。collection这一集合表达式必须是一个数组或者是一个实现了Iterable接口的类对象(例如ArrayList),例如:

int[] a = {2, 3, 4, 5, 6}; for (int element: a) { System.out.println(element); }

打印数组a的每一个元素,一个元素占一行。

2 3 4 5 6

这个循环应该读作"循环a中的每一个元素"(for each element in a)。当然,使用传统的for循环也可以获得同样的效果:

for (int i = 0;i < a.length; i++) { System.out.println(a[i]); }

但是,for each循环语句显得更加简洁、更不易出错,因为你不必为下标的起始值和终止值而操心。
for each循环语句的循环变量将会遍历数组中的每个元素,而不是下标值
总结:如果需要处理一个集合中的所有元素,for each循环语句相对于传统循环语句所做的改进很让人欣喜。然而,很多情况下还是需要使用传统的for循环。例如,如果不希望变量整个集合,或者在循环内部需要使用下标值时。

数组拷贝

在Java中,允许将一个数组变量拷贝到另一个数组变量。这时,两个变量将引用同一个数组:

public class SevenSample { public static void main(String[] args) { int[] smallPrimes = {2, 3, 4, 5, 6, 7, 8}; // 拷贝smallPrimes int[] luckyNumbers = smallPrimes; System.out.println(Arrays.toString(luckyNumbers)); } }

结果

[2, 3, 4, 5, 6, 7]

下图显示了拷贝的结果。

如果希望将一个数组的所有值拷贝到一个新的数组中去,就要使用Arrays类的copyOf方法:

import java.util.Arrays; public class SevenSample { public static void main(String[] args) { int[] smallPrimes = {2, 3, 4, 5, 6, 7}; int[] copiedLuckyNumbers = Arrays.copyOf(smallPrimes, smallPrimes.length); System.out.println(Arrays.toString(copiedLuckyNumbers)); } }

结果如下:

[2, 3, 4, 5, 6, 7]

Array.copyOf方法中,第1个参数是拷贝的对象,第2个参数是新数组的长度。这个方法通常用来增加数组的大小:

luckNumbers = Arrays.copyOf(luckyNumbers, 2 * luckyNumbers.length);

①如果数组元素是数值型,那么额外的元素将被赋值为0;

②如果数组元素是布尔值,那么额外的元素将被赋值为false

③如果长度小于原始数组的长度,则只拷贝前面的值

命令行参数

每一个Java应用程序都有一个带String args[]参数的main方法。这个参数表明main方法将接收一个字符串数组,也就是命令行上指定的参数。
例如,来看下面的程序:

public class EightSample { public static void main(String[] args) { if (args.length == 0 || args[0].equals("-h")) System.out.print("Hello, "); else if (args[0].equals("-g")) System.out.print("Goodbye, "); for (int i = 1; i < args.length; i++) System.out.print(" " + args[i]); System.out.println("!"); } }

如果使用下面这种形式调用这个程序:

java EightSample -g cruel world

args数组将包含以下内容:

args[0]: "-g" args[1]: "cruel" args[2]: "world"

这个程序会输出下面的信息:

数组排序

要想对数值型数组进行排序,可以使用Arrays类中的sort方法:

int[] a = new int[10000]; ... Arrays.sort(a)

这个方法使用了优化的快速排序算法。快速排序算法对于大多数数据集合来说都是效率比较高的。

实战

写一个程序,它产生一个抽彩游戏中的随机数字组合,我们加入抽彩是从49个数字中抽取6个,那么输出的结果为:

下注以下组合,它会使你发财 8 30 32 43 46 49

具体代码如下:

public class NinthSample { public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println("你要抽多少次?"); int k = in.nextInt(); System.out.println("你能抽取的最高数字是什么?"); int n = in.nextInt(); // 从数字1 2 3...n填入数组numbers int[] numbers = new int[n]; for (int i = 0; i < numbers.length; i++) numbers[i] = i + 1; // 抽取k次并放入第二个数组中 int[] result = new int[k]; for (int i = 0; i < result.length; i++) { // 0到n-1之间创建一个随机索引 int r = (int) (Math.random() * n); // 从随机的位置获取元素 result[i] = numbers[r]; // 将最后一个元素移动到随机位置 numbers[r] = numbers[n - 1]; n--; } Arrays.sort(result); System.out.println("下注以下组合,它会使你发财"); for (int r: result) System.out.println(r); } }

代码逻辑分析
  要想选择一个随机的数字集合,就要首先将值1,2,...,n存入数组numbers中:

int[] numbers = new int[n]; for (int i=0; i < numbers.length; i++) numbers[i] = i + 1;

  用第二个数组存放抽取出来的数:

int[] result = new int[k];

  现在,就可以开始抽取k个数了。Math.random方法返回一个0到1之间(包含0,不包含1)的随机浮点数。用n乘以浮点数,就可以得到从0到n-1之间的一个随机数。

int r = (int) (Math.random() * n);

  下面将result的第i个元素设置为numbers[r]存放的数值,最初是r+1。但正如所看到的,numbers数组的内容在每一次抽取之后都会发生变化。

result[i] = numbers[r];

  现在,必须确保不会再次抽取到那个数,因为所有抽彩的数必须不相同。因此,这里用数组中的最后一个数覆盖number[r],并将n减1。

numbers[r] = numbers[n - 1]; n--;

  关键在于每次抽取的都是下标,而不是实际的值。下标指向数组中包含尚未抽取过的值。
  在抽取了k个数之后,可以对result数组进行排序,这样可以让输出效果更好:

Arrays.sort(result); for (int r: result) System.out.println(r); Arrays API

static String toString(xxx[] a) 返回包含a中元素的一个字符串,这些元素用中括号包围、并用逗号分隔。在这个方法以及后面的方法中,数组元素类型xxx可以是`int`、`long`、`short`、`char`、`byte`、`boolean`、`float`或`double`。 static xxx[] copyOf(xxx[] a, int end) static xxx[] copyOfRange(xxx[] a, int start, int end) 返回与a类型相同的一个数组,其长度为`length`或者`end-start`,数组元素为a的值。如果end大于`a.length`,结果会填充0或false值。 static void sort(xxx[] a) 使用优化的快速排序算法对数组进行排序 static int binarySearch(xxx[] a, xxx v) static int binarySearch(xxx[] a, int start, int end, xxx v) 使用二分查找算法在有序数组a中查找值v。如果找到v,则返回相应的下标:否则返回同一个负数值r。`-r-1`是v应插入的位置(为保持a有序)。 static void fill(xxx[] a, xxx v) 将数组的所有数据元素设置为v。 static boolean equals(xxx[] a, xxx[] b) 如果两个数组大小相同,并且下标相同的元素都对应相等,返回true

多维数组

多维数组将使用多个下标访问数组元素,它适用于表示表格或更加复杂的排列形式。
假设需要建立一个数值表格,用来显示不同利率下投资10000美元会增长多少,我们可以使用一个二维数组(也称为矩阵)来存储这些信息。数组命名为balances
在Java中,声明一个二维数组很简单,如下:

double[][] balances;

对数组进行初始化之前是不能使用的。我们可以像下面一样进行初始化:

balances = new double[NYEARS][NRATES];

另外,如果知道数组元素,就可以不调用new,而直接使用简写形式对多维数组进行初始化:

int[][] magicSquare = { {1, 2, 3, 4}, {5, 6, 7, 8} };

一旦数组初始化,就可以利用两个中括号访问各个元素,例如,balance[i][j]

实战

public class ElevenSample { public static void main(String[] args) { // 初始利率 final double STARTRATE = 10; // 列数 final int NRATES = 6; // 行数 final int NYEARS = 10; // 定义利息数组,数组长度为6 double[] interestRate = new double[NRATES]; for (int j = 0; j < interestRate.length; j++) interestRate[j] = (STARTRATE + j) / 100.0; // 定义余额数组,一维表示年,二维表示利率 double[][] balances= new double[NYEARS][NRATES]; Arrays.fill(balances[0], 10000); for (int i = 1; i < balances.length; i++) { for (int j = 0; j < balances[i].length; j++) { double oldBalance = balances[i - 1][j]; double interest = oldBalance * interestRate[j]; balances[i][j] = oldBalance + interest; } } for (int j = 0; j < interestRate.length; j++) System.out.printf("%9.0f%%", 100 * interestRate[j]); System.out.println(); for (double[] row : balances) { for (double b: row) System.out.printf("%10.2f", b); System.out.println(); } } }

结果

不规则数组

暂不讲解

如何从零基础开始学习Java中的数组操作?

本文共计3314个文字,预计阅读时间需要14分钟。

如何从零基础开始学习Java中的数组操作?

数组+数组存储相同类型值的序列。+声明数组+数组是一种数据结构,用于存储同一类型值的集合。+通过一个整型下标(index)或索引(index)可以访问数组中的每个值。例如,如果a是一个整型数组,则可以访问数组中的每个值。

数组

数组存储相同类型值的序列。

声明数组

数组是一种数据结构,用来存储同一类型值的集合。通过一个整型下标(index,或称索引)可以访问数组中的每一个值。例如,如果a是一个整型数组,a[i]就是数组中下标为i的整数。
在声明数组变量时,需要指出数组类型(数据元素类型紧跟[])和数组变量的名字。下面声明了整型数组a:

int[] a;

不过,这条语句只声明了变量a,并没有将a初始化为一个真正的数组。应该使用new操作符创建数组

int[] a = new int[100];

这条语句声明并初始化了一个可以存储100个整数的数组。
数组长度不要求是常量:new int[n]会创建一个长度为n的数组。
一旦创建了数组,就不能再改变它的长度。如果程序运行中需要经常扩展数组的大小,就应该使用另一种数据结构---数组列表(array list)

在Java中,提供了一种创建数组对象并同时提供初始值的简写形式。如下:

int[] a = {2, 3, 5, 7, 11, 13};

请注意,这个语法不需要使用new,甚至不用指定长度。
最后一个值后面允许有逗号,如果你要不断为数组增加值,这会很方便:

String[] authors = {"James", "Kobe", "Curry", "Durant",};

当然,我们也可以声明一个匿名数组;

new int[] {17, 19, 23, 29, 31, 37}

这会分配一个新数组并填入大括号中提供的值。它会统计初始值的个数,并相应地设置数组大小。可以使用这种语法重新初始化一个数组而无须创建新变量。例如:

smallPrimes = new int [] {17, 19, 23, 29, 31, 37};


注意
在Java中,允许有长度为0的数组。在编写一个结果为数组的方发时,如果碰巧结果为空,这样一个长度为0的数组就很有用。可以如下创建长度为0的数组:

new elementType[0]; 或 new elementType2[] {};

访问数组

前面的数组元素的下标为从0~99(不是1~100)。一旦创建了数组,就可以在数组中填入元素,例如,使用一个循环:

int[] a = new int[100]; for (int i = 0; i < 100; i++) { a[i] = i; }

创建一个数字数组时,所有元素都初始化为0,boolean数组的元素会初始化为false。对象数组的元素则初始化为一个特殊值null,表示这些元素还未存放任何对象。刚开始我们可能有些不了解,例如:

String[] names = new String[10];

我们会创建一个包含10个字符串的数组,所有字符串都为null。如果希望这个数组包含空串,必须为元素指定空串:

for (int i=0; i < 10; i++) names[i] = "";

注意:如果创建了一个100个元素的数组,并且试图访问元素a[100](或在0~99之间的任何下标),就会引发array index out of bounds异常。
如果我们想获得数组中的元素个数,可以使用array.length。例如:

for (int i=0; i<a.length; i++) { System.out.println(a[i]); }

for each循环

Java有一种功能很强的循环结构,可以用来依次处理数组(或者其他元素集合)中的每个元素,而不必考虑指定下标值。这种增强的for循环的语句格式为:

for (variable: collection) statement

它定义一个变量用于暂存集合中的每一个元素,并执行相应的语句(当然,也可以是语句块)。collection这一集合表达式必须是一个数组或者是一个实现了Iterable接口的类对象(例如ArrayList),例如:

int[] a = {2, 3, 4, 5, 6}; for (int element: a) { System.out.println(element); }

打印数组a的每一个元素,一个元素占一行。

2 3 4 5 6

这个循环应该读作"循环a中的每一个元素"(for each element in a)。当然,使用传统的for循环也可以获得同样的效果:

for (int i = 0;i < a.length; i++) { System.out.println(a[i]); }

但是,for each循环语句显得更加简洁、更不易出错,因为你不必为下标的起始值和终止值而操心。
for each循环语句的循环变量将会遍历数组中的每个元素,而不是下标值
总结:如果需要处理一个集合中的所有元素,for each循环语句相对于传统循环语句所做的改进很让人欣喜。然而,很多情况下还是需要使用传统的for循环。例如,如果不希望变量整个集合,或者在循环内部需要使用下标值时。

数组拷贝

在Java中,允许将一个数组变量拷贝到另一个数组变量。这时,两个变量将引用同一个数组:

public class SevenSample { public static void main(String[] args) { int[] smallPrimes = {2, 3, 4, 5, 6, 7, 8}; // 拷贝smallPrimes int[] luckyNumbers = smallPrimes; System.out.println(Arrays.toString(luckyNumbers)); } }

结果

[2, 3, 4, 5, 6, 7]

下图显示了拷贝的结果。

如果希望将一个数组的所有值拷贝到一个新的数组中去,就要使用Arrays类的copyOf方法:

import java.util.Arrays; public class SevenSample { public static void main(String[] args) { int[] smallPrimes = {2, 3, 4, 5, 6, 7}; int[] copiedLuckyNumbers = Arrays.copyOf(smallPrimes, smallPrimes.length); System.out.println(Arrays.toString(copiedLuckyNumbers)); } }

结果如下:

[2, 3, 4, 5, 6, 7]

Array.copyOf方法中,第1个参数是拷贝的对象,第2个参数是新数组的长度。这个方法通常用来增加数组的大小:

luckNumbers = Arrays.copyOf(luckyNumbers, 2 * luckyNumbers.length);

①如果数组元素是数值型,那么额外的元素将被赋值为0;

②如果数组元素是布尔值,那么额外的元素将被赋值为false

③如果长度小于原始数组的长度,则只拷贝前面的值

命令行参数

每一个Java应用程序都有一个带String args[]参数的main方法。这个参数表明main方法将接收一个字符串数组,也就是命令行上指定的参数。
例如,来看下面的程序:

public class EightSample { public static void main(String[] args) { if (args.length == 0 || args[0].equals("-h")) System.out.print("Hello, "); else if (args[0].equals("-g")) System.out.print("Goodbye, "); for (int i = 1; i < args.length; i++) System.out.print(" " + args[i]); System.out.println("!"); } }

如果使用下面这种形式调用这个程序:

java EightSample -g cruel world

args数组将包含以下内容:

args[0]: "-g" args[1]: "cruel" args[2]: "world"

这个程序会输出下面的信息:

数组排序

要想对数值型数组进行排序,可以使用Arrays类中的sort方法:

int[] a = new int[10000]; ... Arrays.sort(a)

这个方法使用了优化的快速排序算法。快速排序算法对于大多数数据集合来说都是效率比较高的。

实战

写一个程序,它产生一个抽彩游戏中的随机数字组合,我们加入抽彩是从49个数字中抽取6个,那么输出的结果为:

下注以下组合,它会使你发财 8 30 32 43 46 49

具体代码如下:

public class NinthSample { public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println("你要抽多少次?"); int k = in.nextInt(); System.out.println("你能抽取的最高数字是什么?"); int n = in.nextInt(); // 从数字1 2 3...n填入数组numbers int[] numbers = new int[n]; for (int i = 0; i < numbers.length; i++) numbers[i] = i + 1; // 抽取k次并放入第二个数组中 int[] result = new int[k]; for (int i = 0; i < result.length; i++) { // 0到n-1之间创建一个随机索引 int r = (int) (Math.random() * n); // 从随机的位置获取元素 result[i] = numbers[r]; // 将最后一个元素移动到随机位置 numbers[r] = numbers[n - 1]; n--; } Arrays.sort(result); System.out.println("下注以下组合,它会使你发财"); for (int r: result) System.out.println(r); } }

代码逻辑分析
  要想选择一个随机的数字集合,就要首先将值1,2,...,n存入数组numbers中:

int[] numbers = new int[n]; for (int i=0; i < numbers.length; i++) numbers[i] = i + 1;

  用第二个数组存放抽取出来的数:

int[] result = new int[k];

  现在,就可以开始抽取k个数了。Math.random方法返回一个0到1之间(包含0,不包含1)的随机浮点数。用n乘以浮点数,就可以得到从0到n-1之间的一个随机数。

int r = (int) (Math.random() * n);

  下面将result的第i个元素设置为numbers[r]存放的数值,最初是r+1。但正如所看到的,numbers数组的内容在每一次抽取之后都会发生变化。

result[i] = numbers[r];

  现在,必须确保不会再次抽取到那个数,因为所有抽彩的数必须不相同。因此,这里用数组中的最后一个数覆盖number[r],并将n减1。

numbers[r] = numbers[n - 1]; n--;

  关键在于每次抽取的都是下标,而不是实际的值。下标指向数组中包含尚未抽取过的值。
  在抽取了k个数之后,可以对result数组进行排序,这样可以让输出效果更好:

Arrays.sort(result); for (int r: result) System.out.println(r); Arrays API

static String toString(xxx[] a) 返回包含a中元素的一个字符串,这些元素用中括号包围、并用逗号分隔。在这个方法以及后面的方法中,数组元素类型xxx可以是`int`、`long`、`short`、`char`、`byte`、`boolean`、`float`或`double`。 static xxx[] copyOf(xxx[] a, int end) static xxx[] copyOfRange(xxx[] a, int start, int end) 返回与a类型相同的一个数组,其长度为`length`或者`end-start`,数组元素为a的值。如果end大于`a.length`,结果会填充0或false值。 static void sort(xxx[] a) 使用优化的快速排序算法对数组进行排序 static int binarySearch(xxx[] a, xxx v) static int binarySearch(xxx[] a, int start, int end, xxx v) 使用二分查找算法在有序数组a中查找值v。如果找到v,则返回相应的下标:否则返回同一个负数值r。`-r-1`是v应插入的位置(为保持a有序)。 static void fill(xxx[] a, xxx v) 将数组的所有数据元素设置为v。 static boolean equals(xxx[] a, xxx[] b) 如果两个数组大小相同,并且下标相同的元素都对应相等,返回true

多维数组

多维数组将使用多个下标访问数组元素,它适用于表示表格或更加复杂的排列形式。
假设需要建立一个数值表格,用来显示不同利率下投资10000美元会增长多少,我们可以使用一个二维数组(也称为矩阵)来存储这些信息。数组命名为balances
在Java中,声明一个二维数组很简单,如下:

double[][] balances;

对数组进行初始化之前是不能使用的。我们可以像下面一样进行初始化:

balances = new double[NYEARS][NRATES];

另外,如果知道数组元素,就可以不调用new,而直接使用简写形式对多维数组进行初始化:

int[][] magicSquare = { {1, 2, 3, 4}, {5, 6, 7, 8} };

一旦数组初始化,就可以利用两个中括号访问各个元素,例如,balance[i][j]

实战

public class ElevenSample { public static void main(String[] args) { // 初始利率 final double STARTRATE = 10; // 列数 final int NRATES = 6; // 行数 final int NYEARS = 10; // 定义利息数组,数组长度为6 double[] interestRate = new double[NRATES]; for (int j = 0; j < interestRate.length; j++) interestRate[j] = (STARTRATE + j) / 100.0; // 定义余额数组,一维表示年,二维表示利率 double[][] balances= new double[NYEARS][NRATES]; Arrays.fill(balances[0], 10000); for (int i = 1; i < balances.length; i++) { for (int j = 0; j < balances[i].length; j++) { double oldBalance = balances[i - 1][j]; double interest = oldBalance * interestRate[j]; balances[i][j] = oldBalance + interest; } } for (int j = 0; j < interestRate.length; j++) System.out.printf("%9.0f%%", 100 * interestRate[j]); System.out.println(); for (double[] row : balances) { for (double b: row) System.out.printf("%10.2f", b); System.out.println(); } } }

结果

不规则数组

暂不讲解

如何从零基础开始学习Java中的数组操作?