一、数组声明和实例化
声明了一个数组
int[] numbers;
int number[];
实例化数组
numbers = new int[6];
或两步一起
int[]numbers=new int[6];
或者直接 往里面放数据
int[] days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
可以用下标读取数组中的元素
number[0]=20;
与基本数据类型不同的是,在声明基本数据类型的时候,其变量的大小可以直接确定,而数组则要视情况而定,【6】就是这个数组大小的声明。
基础数据类型的声明
数组的声明
数组的大小必须是一个非负数,在标记数组大小的时候,经常使用关键字final,一旦数组的大小被确定,就无法改变。
二、“Enhanced for loop”
1、形式
Java为了数组提供了特殊增强版的for循环,形式如下:
for (datatype elementVariable : array)
statement;
datatype是数组中储存的变量的类型
elementVariable是对每个数组中变量取的名字
array是数组名
2、不能使用这种for循环的情况
增强版的for循环好处显而易见,比如你不需要知道数组的长度,不需要一个变量来储存数组的下标,但是也有一些情况不能使用这种for循环:
如果需要更改数组元素的内容
如果需要按相反顺序处理数组元素
如果您需要访问某些数组元素,但不是所有数组元素
如果需要同时使用循环中的两个或多个阵列
如果需要引用特定元素的下标号
三、数组的拷贝
1、数组变量的重新分配
// Create an array referenced by the numbers variable.
int[] numbers = new int[10];
// Reassign numbers to a new array.
numbers = new int[5];
2、数组的拷贝
数组是一个对象,而对象和指向它的变量是有区别的。数组和指向数组的变量是两个实体,下面的拷贝只拷贝了变量,而没有拷贝数组。
int[] array1 = { 2, 4, 6, 8, 10 };
int[] array2 = array1; // This does not copy array1.
这个拷贝只是将array1这个变量拷贝了一份给变量array2,这时候array1和array2都指向同一个数组。
真正对数组的拷贝如下
int[] firstArray = { 5, 10, 15, 20, 25 };
int[] secondArray = new int[5];
for (int index = 0; index < firstArray.length; index++)
secondArray[index] = firstArray[index];
四、将数组作为参数传递给方法
1、传递数组中的元素
/**
This program demonstrates passing individual array
elements as arguments to a method.
*/
public class PassElements
{
public static void main(String[] args)
{
int[] numbers = {5, 10, 15, 20, 25, 30, 35, 40};
for (int index = 0; index < numbers.length; index++)
showValue(numbers[index]);
}
/**
The showValue method displays its argument.
@param n The value to display.
*/
public static void showValue(int n)
{
System.out.print(n + " ");
}
}
2、传递整个数组
public static void showArray(int[] array)
{
for (int i = 0; i < array.length; i++)
System.out.print(array[i] + " ");
}
将数组作为参数传递实际上就是将一个对象传递给方法,数组本身没有被传递,被传递的是数组的引用
五、一些数组中的算法
1、比较两个数组
比较数组显然不能用“==”,“==”比较的是两个数组变量的引用是否时同一个引用,而并不是比较数组中的内容,比数组是否相等的算法如下:
int[] firstArray = { 2, 4, 6, 8, 10 };
int[] secondArray = { 2, 4, 6, 8, 10 };
boolean arraysEqual = true; // Flag variable
int index = 0; // Loop control variable
// First determine whether the arrays are the same size.
if (firstArray.length != secondArray.length)
arraysEqual = false;
// Next determine whether the elements contain the same data.
while (arraysEqual && index < firstArray.length)
{
if (firstArray[index] != secondArray[index])
arraysEqual = false;
index++;
}
if (arraysEqual)
System.out.println("The arrays are equal.");
else
System.out.println("The arrays are not equal.");
首先判断长度是否相等,然后用while循环判断内容是否相等
2、寻找数组中的最大(最小)值
int highest = numbers[0];
for (int index = 1; index < numbers.length; index++)
{
if (numbers[index] > highest)
highest = numbers[index];
}
3、举例
LaClaire博士在这学期的化学课上进行了一系列的考试。最后上学期,她在平均分数之前先降低每个学生的最低考试分数。她要求你编写一个程序,读取学生的考试分数作为输入,并计算除去最低分后的平均值
/**
The Grader class calculates the average
of an array of test scores, with the
lowest score dropped.
*/
public class Grader
{
// The testScores field is a variable
// that will reference an array
// of test scores.
private double[] testScores;
/**
Constructor
@param scoreArray An array of test scores.
*/
public Grader(double[] scoreArray)
{
// Assign the array argument to
// the testScores field.
testScores = scoreArray;
}
/**
getLowestScore method
@return The lowest test score.
*/
public double getLowestScore()
{
double lowest; // To hold the lowest score
// Get the first test score in the array.
lowest = testScores[0];
// Step through the rest of the array. When
// a value less than lowest is found, assign
// it to lowest.
for (int index = 1; index < testScores.length; index++)
{
if (testScores[index] < lowest)
lowest = testScores[index];
}
// Return the lowest test score.
return lowest;
}
/**
getAverage method
@return The average of the test scores
with the lowest score dropped.
*/
public double getAverage()
{
double total = 0; // To hold the score total
double lowest; // To hold the lowest score
double average; // To hold the average
// If the array contains less than two test
// scores, display an error message and set
// average to 0.
if (testScores.length < 2)
{
System.out.println("ERROR: You must have at " +
"least two test scores!");
average = 0;
}
else
{
// First, calculate the total of the scores.
for (double score : testScores)
total += score;
// Next, get the lowest score.
lowest = getLowestScore();
// Subtract the lowest score from the total.
total −= lowest;
// Get the adjusted average.
average = total / (testScores.length - 1);
}
// Return the adjusted average.
return average;
}
}
import java.util.Scanner;
/**
This program gets a set of test scores and
uses the Grader class to calculate the average
with the lowest score dropped.
*/
public class CalcAverage
{
public static void main(String[] args)
{
int numScores; // To hold the number of scores
// Create a Scanner object for keyboard input.
Scanner keyboard = new Scanner(System.in);
// Get the number of test scores.
System.out.print("How many test scores do you have? ");
numScores = keyboard.nextInt();
// Create an array to hold the test scores.
double[] scores = new double[numScores];
// Get the test scores and store them
// in the scores array.
for (int index = 0; index < numScores; index++)
{
System.out.print("Enter score #" +
(index + 1) + ": ");
scores[index] = keyboard.nextDouble();
}
// Create a Grader object, passing the
// scores array as an argument to the
// constructor.
Grader myGrader = new Grader(scores);
// Display the adjusted average.
System.out.println("Your adjusted average is " +
myGrader.getAverage());
// Display the lowest score.
System.out.println("Your lowest test score was " +
myGrader.getLowestScore());
}
}
注意学习例子中两个类之间的关系以及主函数中对Grader类中方法的调用。
Grader类中的方法都是实例方法,也就是说你需要创建Grader类对象,并对这个对象使用这个方法才行。
同时Grader类中的构造器把主函数里的变量复制了一份使用(虽然复制前后的变量一模一样),这种构造器的使用方法使得Grader类中的方法更加明了,值得学习。
六、不知道数组元素的内容的情况
有时候不知道数组中的元素的内容和数量,一个比较简单的方法是:创造一个非常非常大的数组,可以容下足够多的内容,eg:
final int ARRAY_SIZE = 100;
int[] array = new int[ARRAY_SIZE];
int count = 0;
每次当我们增加数组中的内容时,用一个递增的count变量计数:
Scanner keyboard = new Scanner(System.in);
System.out.print("Enter a number or −1 to quit: ");
number = keyboard.nextInt();
while (number != −1 && count < array.length)
{
array[count] = number;
count++;
System.out.print("Enter a number or −1 to quit: ");
number = keyboard.nextInt();
}
如果将部分填充的数组作为参数传递给方法,则保存数组中的项的变量也必须作为参数传递。否则,该方法将无法确定存储在数组中的数据哪些是真正的数据,哪些是自动填充的数值。
七、将数组内容写入文档或从文档中读取内容生成数组
(1)将数组内容写入文档
int[] numbers = { 10, 20, 30, 40, 50 };
// Open the file.
PrintWriter outputFile = new PrintWriter("Values.txt");
// Write the array elements to the file.
for (int index = 0; index < numbers.length; index++)
outputFile.println(numbers[index]);
// Close the file.
outputFile.close();
(2)从文档中读取内容生成数组
final int SIZE = 5;
int[] numbers = new int[SIZE];
int index = 0; // Loop control variable
// Open the file.
File file = new File("Values.txt");
Scanner inputFile = new Scanner(file);
// Read the file contents into the array.
while (inputFile.hasNext() && index < numbers.length)
{
numbers[index] = inputFile.nextInt();
index++;
}
// Close the file.
inputFile.close();
八、将数组作为方法的返回值
除了接受数组作为参数外,方法还可以返回数组。
public static double[] getArray()
{
double[] array = { 1.2, 2.3, 4.5, 6.7, 8.9 };
return array;
}
九、string数组
1、string数组数引用的数组
你可用如下方式初始化一个string数组
String[] names = { "Bill", "Susan", "Steven", "Jean" };
显然,如果你想用一个数组去储存string类的数据,你需要创造一系列对string类对象的引用,所以事实上string类的数组时一系列对数组对象的引用所构成的数组。
names数组中的每个元素都是对String对象的引用。name[0]元素引用了a字符串对象包含“Bill”,name[1]元素引用包含“Susan”的字符串对象。
与基本数据类型的数组一样,如果你不提供初始化的数据,你需要用关键字new去创建一个数组,这时数组中的内容被设置为null:
final int SIZE = 4;
String[] names = new String[SIZE];
2、用string数组中的元素去调用string类中的方法
string数组中的元素实际上就是一个string类的实例,因此可以用string数组中的元素去调用string类的方法:
System.out.println(names[0].toUpperCase());
下面的代码显示了另一个示例。它使用names数组的第三元素来调用charAt方法。当执行此代码时,存储在name[3]中的字符串的第一个字符将被赋值给letter:
// Declare a char variable named letter.
char letter;
// Assign the first character in names[3] to letter.
letter = names[3].charAt(0);
十、对象的数组(arrays of objects)
1、对象的数组的初始化
注意对数组中对象初始化的时候,注意和基础数据类型的不同
final int NUM_ACCOUNTS = 5;
BankAccount[] accounts = new BankAccount[NUM_ACCOUNTS];
在这时,虽然new了一个bank account类的数组,但是数组中的每个元素都被初始化为null,所以你必须手动单独的指定对象的引用:
for (int index = 0; index < accounts.length; index++)
accounts[index] = new BankAccount();
在这段代码中,为每个对象调用无参数构造函数。BankAccount类有一个无参数构造函数,它将0.0赋值给balance字段。每个元素在执行循环后,accounts数组将引用一个BankAccount对象。
2、对象的数组的方法调用
accounts[2].setBalance(2500.0);
accounts[2].withdraw(500.0);