3.10.6 多维数组
多维数组将使用多个下标访问数组元素,它适用于表示表格或更加复杂的排列形式.在Java中,声明一个二维数组相当简单.例如:
double [][] balances;
与一维数组一样,在调用 new 对多维数组进行初始化之前不能使用它.在这里可以这样初始化:
balances = new double[NYEARS][NRATES];
另外,如果知道数组元素,就可以不调用 new,而直接使用简化的书写形式对多维数组进行初始化.例如:
int[][] magicSquare =
{
{1, 2, 3},
{2, 3, 4}
};
一旦数组被初始化,就可以利用两个方括号访问每个元素,例如,balances[i][j].
注释: for each 循环语句不能自动处理二维数组的每一个元素.它是按照行,也就是一维数组处理的.要想访问二维数组a的所有元素,需要使用两个嵌套的循环,如下所示:
for (double[] row : a)
for (double value : row)
do something with value
提示:要想快速地打印出一个二维数组的数据元素列表,可以调用:
System.out.println(Arrays.deepToString(a));
输出格式为:
[[1, 2, 3], [2, 3, 4]]
CompoundInterest.java如下所示:
public class CompoundInterest
{
public static void main(String[] args)
{
final double STARTRATE = 10;
final int NRATES = 6;
final int NYEARS = 10;
// set interest rates to 10 ... 15%
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];
// set initial balances to 10000
for (int j = 0; j < balances[0].length; j++)
balances[0][j] = 10000;
// compute interest for future years
for (int i = 1; i < balances.length; i++)
{
for (int j = 0; j < balances[i].length; j++)
{
// get last year's balances from previous row
double oldBalance = balances[i - 1][j];
// compute interest
double interest = oldBalance * interestRate[j];
// compute this year's balances
balances[i][j] = oldBalance + interest;
}
}
// print one row of interest rates
for (int j = 0; j < interestRate.length; j++)
System.out.printf("%9.0f%%", 100 * interestRate[j]);
System.out.println();
// print balance table
for (double[] row : balances)
{
// print table row
for (double b : row)
System.out.printf("%10.2f", b);
System.out.println();
}
}
}
3.10.7 不规则数组
Java实际上没有多维数组,只有一维数组.多维数组被解释为"数组的数组".例如,在前面的示例中,balances数组实际上是一个包含10个元素的数组,而每个元素又是一个由6个浮点数组成的数组.
表达式balances[i]引用第i个子数组,也就是二维表的第i行.它本身也是一个数组,balances[i][j]引用这个数组的第j项.
由于可以单独地存取数组的某一行,所以可以让两行交换.
double[] temp = balances[i];
balances[i] = balances[i + 1];
balances[i + 1] = temp;
还可以方便地构造一个"不规则"数组,即数组的每一行有不同的长度.下面是一个典型的示例.
public class LotteryArray
{
public static void main(String[] args)
{
final int NMAX = 10;
// allocate triangular array
int[][] odds = new int[NMAX + 1][];
for (int n = 0; n <= NMAX; n++)
odds[n] = new int[n + 1];
// fill triangular array
for (int n = 0; n < odds.length; n++)
for (int k = 0; k < odds[n].length; k++)
{
int lotteryOdds = 1;
for (int i = 1; i <= k; i++)
lotteryOdds = lotteryOdds * (n - i + 1) / i;
odds[n][k] = lotteryOdds;
}
// print triangular array
for (int[] row : odds)
{
for (int odd : row)
System.out.printf("%4d", odd);
System.out.println();
}
}
}
不规则数组显示如下:
注释:在C++中,Java的声明
double[][] balances = new double[10][6]; // Java
不同于
double balances[10][6]; // C++
也不同于
double (*balances)[6] = new double[10][6]; // C++
而是分配了一个包含10个指针的数组:
double** balances = new double*[10]; // C++
然后,指针数组的每一个元素被填充了一个包含6个数字的数组:
for (i = 0; i < 10; i++)
balances[i] = new double[6];
庆幸的是,当创建 new double[10][6]时,这个循环将自动地执行.当不需要规则的数组时,只能单独地创建行数组.