数组
数组是一种数据结构,用来存储同一类型值得集合。通过一个整型下标可以访问数组中的每一个值。
在声明数组变量时,需要指出数组类型和数组变量的名字。下面声明了整型数组a:
int[] a;
不过,这条语句只是声明了数组变量,但是还未完成初始化。使用new来初始化一个数组:
int[] a = new int[100];
注意:数组中的下标不是从1开始,而是从0开始,也就是说上面的数组a的下标是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];
for(int i=0;i<10;i++){
names[i]="";
}
上面的程序第一句话创建了一个String类型,包含10个字符串的数组,该数组没有存储任何对象,其值都是null,接下来使用for循环为其赋值,当循环执行完毕时,数组的每个元素的值都是空字符串。
警告:如果创建了一个长度为100的数组,并且试图访问a[100](或者在0~99之外的下标),程序会引发异常(array index out of bounds)而终止执行。
要想获得数组的长度,可以通过array.length获取数组长度。数组一旦创建,就不能改变其大小,但是可以改变数组中元素的大小。如果经常需要在运行过程中扩展数组的大小,就应该使用另一种数据结构----数组列表(array list),以后会写到。
(一)for each循环
Java中有一种循环,可以用来依次处理数组中的每个元素(其他类型的元素集合也可以)而不必操心下标值。这种增强for循环为:
for(variable:collection) statement
例如:
for(int element:a){
System.out.println(element);
}
注意:for each循环语句显得更加简洁,不易出错。
(二)数组初始化以及匿名数组
在Java中,提供了一种创建数组对象并同时赋予初始值的简化书写形式,下面是个例子:
int[] smallPrimes={2,3,5,7,11,13};
在使用这种语句时,不需要使用new关键字;甚至还可以初始化一个匿名的数组:
new int[] {17,19,23,29,31,37};
这种方法将创建一个新数组并利用括号中提供的值进行初始化,数组的大小就是初始值的个数。
(三)数组拷贝
在Java中,允许将一个数组变量拷贝给另一个数组变量。这是两个变量将引用同一个数组:
int[] luckyNumbers = smallPrimes;
luckyNumbers[5]=12;//now samllPrimes[5] is also 12
如果希望将一个数组的所有值拷贝到一个新的数组中去,就要使用Arrays类的copyOf方法:
int[] copiedLuckyNumbers = Arrays.copyOf(luckyNumbers,luckyNumbers.length);//第二个参数是新数组的长度。这个方法通常用来增加数组的大小。
luckyNumbers = Arrays.copyOf(luckyNumbers,2*luckyNumbers.length);
如果数组元素是数值型,那么多余的元素将被赋值为0,如果数组元素是boolean,多余元素就被赋值为false;相反,如果长度小于原始数组的长度,则只拷贝最前面的数据元素。
(四) 数组排序
要想对数值型数组进行排序,可以使用Arrays类中的sort方法,这个方法使用了优化的快速排序算法。
package CoreJava;
import java.util.Arrays;
import java.util.Scanner;
/**
* This program demos=nstrates array manipulation.
*
*/
public class LotteryDrawing {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("How many numbers do you need to draw?");
int k = in.nextInt();
System.out.println("What's the highest number you can draw?");
int n = in.nextInt();
//从n个数中抽取,那么久将这n个数放在numbers数组内,从1到n
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<k;i++) {
//创建一个0到n-1的数,是为了从数组numbers中抽取某个数,这个r是下标
int r = (int)(Math.random()*n);
result[i] = numbers[r];
//把最后一个数赋值给刚才被抽取的数,然后n--,就使得刚才被抽取的数已经在数组之外,而数组的最后一个数,
//而数组的最后一个数也一直在数组中
numbers[r]=numbers[n-1];
n--;
}
Arrays.sort(result);
System.out.println("Bet the following combination.It'll make you rich!");
for(int r : result) {
System.out.println(r);
}
}
}
冒泡排序:
package Sort;
import java.util.Random;
/**
* 冒泡排序
*原理:N个数字循环就需要N-1次循环,没i趟的排序次数为N-i次,所以可以利用双层循环
*/
public class BubbleSort {
public static void main(String[] args) {
Random ran = new Random();
int[] sort = new int[10];
for(int i=0;i<sort.length;i++) {
sort[i]=ran.nextInt(50);
}
System.out.println("排序前的数组:");
for(int i:sort) {
System.out.print(i+" ");
}
System.out.println("");
bubbleSort2(sort);
System.out.println("排序后的数组:");
for(int i:sort) {
System.out.print(i+" ");
}
}
/*
* 从下往上扫描,依次比较相邻的两个数,如果后一个数比前一个数小,则交换位置。
*/
private static void bubbleSort(int[] sort) {
for(int i=0;i<sort.length-1;i++) {
for(int j=sort.length-1;j>0;j--) {
if(sort[j]<sort[j-1]) {
int temp =sort[j-1];
sort[j-1]=sort[j];
sort[j]=temp;
}
}
}
}
/*
*从上往下扫描,依次比较相邻的两个数,如果后一个数比前一个数小,则交换位置
*/
private static void bubbleSort2(int[] sort) {
for(int i=0;i<sort.length;i++) {
for(int j=1;j<sort.length-i;j++) {
if(sort[j]<sort[j-1]) {
int temp =sort[j-1];
sort[j-1]=sort[j];
sort[j]=temp;
}
}
}
}
}
(五)多维数组
多维数组将使用多个下标访问数组元素,它适用于表示表格或更加复杂的排列形式。在Java中,声明一个二维数组相当简单,例如:
double[][] balances;
与一维数组一样,在调用new对多维数组初始化之前是不能使用的。
balances = new double[NYEARS][NRATES];
L另外,如果知道数组元素,就可以不用new关键字,像一维数组一样直接写。
int[][] magicSquare = {
{16,3,2,13},
{5,10,11,8},
{9,6,7,12},
{4,15,14,1}
};
一旦数组被初始化,就可以利用两个方括号访问每个元素,例如,balances[i][j];
注意:for each循环语句不能自动处理二维数组的每一个元素。它是按照行,也就是一维数组处理的。要想访问二维数组a的所有元素,需要使用两个嵌套的循环:
for(double[] row : a){
for(double value : row){
do something with value
}
}
提示:要想快速的打印一个二维数组的数据元素列表,可以调用:
System.out.println(Arrays.deepToString(a));
程序示例:用来显示在不同利率下投资$10000会增长多少,利息每年兑现,而且又被用于投资。
10% | 11% | 12% | 13% | 14% | 15% |
10000.0 | 10000.0 | 10000.0 | 10000.0 | 10000.0 | 10000.0 |
11000.00 | 11100.00 | 11200.00 | 11300.00 | 11400.00 | 11500.00 |
12100.00 | 12321.00 | 12544.00 | 12769.00 | 12996.00 | 13225.00 |
13310.00 | 13676.31 | 14049.28 | 14428.97 | 14815.44 | 15208.75 |
14641.00 | 15180.70 | 15735.19 | 16304.74 | 16889.60 | 17490.06 |
16105.10 | 16850.58 | 17623.42 | 18424.35 | 19254.15 | 20113.57 |
17715.61 | 18704.15 | 19738.23 | 20819.52 | 21949.73 | 23130.61 |
19487.17 | 20761.60 | 22106.81 | 23526.05 | 25022.69 | 26600.20 |
21435.89 | 23045.38 | 24759.63 | 26584.44 | 28525.86 | 30590.23 |
23579.48 | 25580.37 | 27730.79 | 30040.42 | 32519.49 | 35178.76 |
package CoreJava;
public class CompoundInterest {
public static void main(String[] args) {
final double STARTRATE = 10;
final int NRATES = 6;
final int NYEARS = 10;
// 设置利率的增长 从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];
for(int j=0;j<balances[0].length;j++) {
balances[0][j] = 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中实际上没有多维数组,只有一维数组。多维数组被解释为“数组的数组”。例如在前面的示例中,实际上是一个包含10个元素的数组,而每个元素又是一个6个浮点数组成的数组。
表达式balances[i]表示引用第i个子数组,也就是二维表的第i行。它本身也是一个数组,balances[i][j]引用这个数组的第j项。
由于可以单独的存取数组的某一行,所以可以让两行交换。
<span style="color:#ff0000">double[] temp = balances[i];
balances[i]=balances[i+1};
balances[i+1]=temp;</span>
也可以构造一个不规则数组,即数组的每一行有不同的长度。
package CoreJava;
/**
* This program demonstrates a triangular array.
*
*/
public class LotteryArray {
public static void main(String[] args) {
final int NMAX =8;
int[][] odds = new int[NMAX+1][];
for(int n=0;n<=NMAX;n++) {
odds[n] = new int[n+1];
}
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-1+1)/i;
}
odds[n][k] = lotteryOdds;
}
}
for(int[] row : odds) {
for(int odd : row) {
System.out.printf("%4d", odd);
}
System.out.println();
}
}
}
至此,已经看到了Java语言的基本程序结构。