CoreJava读书笔记--数组

数组

数组是一种数据结构,用来存储同一类型值得集合。通过一个整型下标可以访问数组中的每一个值。

在声明数组变量时,需要指出数组类型和数组变量的名字。下面声明了整型数组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.
 * @author 弓长小月
 *
 */
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;

/**
 * 冒泡排序
 * @author 弓长小月
 *原理: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项。

由于可以单独的存取数组的某一行,所以可以让两行交换。

double[] temp = balances[i];
balances[i]=balances[i+1};
balances[i+1]=temp;
也可以构造一个不规则数组,即数组的每一行有不同的长度。
package CoreJava;

/**
 * This program demonstrates a triangular array.
 * @author 弓长小月
 *
 */
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语言的基本程序结构。






猜你喜欢

转载自blog.csdn.net/zxyy2627/article/details/79635241
今日推荐