Java学习笔记(7)Single-Dimentional Arrays

7.2 Array Basics

数组是一组相同类型数据的集合。你不需要关心这些数据在内存中如何排列,因为Java不能通过地址访问元素。


7.2.1 Declaring Array Variables

datatype[] arrayRefVar; //推荐写法

例如: double[] myList; //声明myList是数组变量(指针,在Stack中),但是目前数组为null,还没有空间(在Heap中)存放数组元素

datatype arrayRefVar[]; //可用,不推荐

        例如: double myList[];


7.2.2 Creating Arrays

arrayRefVar = new datatype[arraySize];

例如:myList = new double[10]; //Java数组是动态创建的,new的作用是分配数组空间。此处一定要用new,这点与C语言不同

myList[0] 表示数组第一个元素

myList[9] 表示数组最后一个元素

声明的同时创建数组

datatype[] arrayRefVar = new datatype[arraySize];

double[] myList = new double[10]; //推荐写法

datatype arrayRefVar[] = new datatype[arraySize];

double myList[] = new double[10]; //不推荐


7.2.3 Array Size and Default Values

数组一旦创建(注意不是声明)后,长度就固定不变了。其实数组是一个对象,这个对象有一个属性length存储了数组长度。用法如下:

arrayRefVar.length

例如前一个例子, myList.length 是 10

和C不同,Java会自动为数组赋初值,所以创建数组(new)之后,每一个元素都有默认值。具体规定如下:

1、0 是所有数值类型的初值(整数、浮点数)

2、‘\u0000’ 是 char 类型的初值

3、false 是 boolean 类型的初值


7.2.4 Accessing Array Elements

数组元素通过下标访问,下标从0开始编号,最大下标是数组长度-1。例如有一个数组arrayRefVar,无论它类型如何,可用下标一定是:

0…arrayRefVar.length-1

也就是这个数组的元素是:

arrayRefVar[0],arrayRefVar[1],arrayRefVar[2],…,arrayRefVar[arrayRefVar.length-1]

7.2.5 Array Initializers

声明,创建和初始化数组也可以一步完成(注意此处不用new):

double[] myList = {1.9, 2.9, 3.4, 3.5};

此时数组myList大小为4

注意:采用数组初始化,不能出现new。

两种写法对比

double[] myList = {1.9, 2.9, 3.4, 3.5};

上个例子的等价写法:

double[] myList = new double[4];

myList[0] = 1.9;

myList[1] = 2.9;

myList[2] = 3.4;

myList[3] = 3.5;

注意:使用简化方式的初始化,所有代码必须在一条语句写完,不能拆开,所以下面这个写法就是错误的:

double[] myList;

myList = {1.9, 2.9, 3.4, 3.5};

7.2.6 Processing Arrays

When processing array elements, you will often use a for loop—for two reasons:

■ All of the elements in an array are of the same type. They are evenly processed in the same fashion repeatedly using a loop.

■ Since the size of the array is known, it is natural to use a for loop.

Assume the array is created as follows:

double[] myList = new double[10];

The following are some examples of processing arrays.

1. 用输入值初始化数组

Initializing arrays with input values: The following loop initializes the array myList with user input values.

java.util.Scanner input = new java.util.Scanner(System.in);
System.out.print("Enter " + myList.length + " values: ");
for (int i = 0; i < myList.length; i++)
        myList[i] = input.nextDouble();

2. 用随机值初始化数组

Initializing arrays with random values: The following loop initializes the array myList with random values between 0.0 and 100.0, but less than 100.0.

for (int i = 0; i < myList.length; i++) {
	myList[i] = Math.random() * 100;
}

3. 打印数组

Displaying arrays: To print an array, you have to print each element in the array using a loop like the following:

for (int i = 0; i < myList.length; i++) {
	System.out.print(myList[i] + " ");
}

4.数组求和

Summing all elements: Use a variable named total to store the sum. Initially total is 0. Add each element in the array to total using a loop like this:

double total = 0;
for (int i = 0; i < myList.length; i++) {
	total += myList[i];
}

5. 找数组最大值

Finding the largest element: Use a variable named max to store the largest element. Initially max is myList[0]. To find the largest element in the array myList, compare each element with max, and update max if the element is greater than max.

double max = myList[0];
for (int i = 1; i < myList.length; i++) {
	if (myList[i] > max) max = myList[i];
}

6. 找数组最大元素的最小下标值

Finding the smallest index of the largest element: Often you need to locate the largest element in an array. If an array has multiple elements with the same largest value, find the smallest index of such an element.

Suppose the array myList is {153455}. The largest element is and the smallest index for is 1. Use a variable named max to store the largest element and a variable named indexOfMax to denote the index of the largest element. Initially max is myList[0], and indexOfMax is 0.

Compare each element in myList with max, and update max and indexOfMax if the element is greater than max.

double max = myList[0];
int indexOfMax = 0;
for (int i = 1; i < myList.length; i++) {
	if (myList[i] > max) {
		max = myList[i];
		indexOfMax = i;
	}
}

7. 打乱数组

Random shuffling: In many applications, you need to randomly reorder the elements in an array. This is called shuffling. To accomplish this, for each elementmyList[i], randomly generate an index and swap myList[i] with myList[j], as follows:

for (int i = myList.length – 1; i > 0; i––) {
	// Generate an index j randomly with 0 <= j <= i
	int j = (int)(Math.random()* (i + 1));
	// Swap myList[i] with myList[j]
	double temp = myList[i];
	myList[i] = myList[j];
	myList[j] = temp;
}


8. 元素移动(左移1位)

Shifting elements: Sometimes you need to shift the elements left or right. Here is an example of shifting the elements one position to the left and filling the last element with the first element:

double temp = myList[0]; // Retain the first element
// Shift elements left
for (int i = 1; i < myList.length; i++) {
	myList[i - 1] = myList[i];
}
// Move the first element to fill in the last position
myList[myList.length - 1] = temp;


9. 用数组查表

Simplifying coding: Arrays can be used to greatly simplify coding for certain tasks. For example, suppose you wish to obtain the English name of a given month by its number.

If the month names are stored in an array, the month name for a given month can be accessed simply via the index. The following code prompts the user to enter a month number and displays its month name:

String[] months = {"January""February", ..., "December"};

System.out.print("Enter a month number (1 to 12): ");

int monthNumber = input.nextInt();

System.out.println("The month is " + months[monthNumber -1]);

If you didn’t use the months array, you would have to determine the month name using a lengthy multi-way if-else statement as follows:

if (monthNumber == 1)

System.out.println("The month is January");

else if (monthNumber == 2)

System.out.println("The month is February");

...

else

System.out.println("The month is December");


7.2.7 Foreach Loops

JDK 1.5开始,for循环多了一种用法:从头到尾遍历。这种用法称为for-each循环。例如打印 myList数组的每一个元素值,可以这样写: 

for (double value: myList)

System.out.println(value); 

更一般的,for-each循环的语法是: 

for (elementType value: arrayRefVar) {

  // Process the value

如果不想从头到尾遍历数组,或者需要跳过某几个下标,那只能老老实实用以前版本的for。


7.3 Case study

编程练习:数字覆盖问题

从键盘输入一批以0结尾的整数,编程判断这批数是否覆盖了1 到 99 之间的每一个整数。换句话说,就是判断1,2,3…,99的每一个整数是否都出现过。

解题思路:

首先创建具有100个元素的boolean数组isCovered。用下标i表示数字i是否出现。下标0这里不用,因为只需要判断1..99。初始的时候,所有元素的值都是false,表示数字未出现。每读到一个整数,就将对应的元素设为true。

所有数据读完后,判断数组元素是否全为true即可。

import java.util.Scanner;
public class LottoNumbers {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		boolean[] isCovered = new boolean[100]; //默认false
		// 读数并设置相应标志	
		int number = input.nextInt();
		while (number != 0) {
			isCovered[number] = true; 
			number = input.nextInt();
		}
		//检查是否全覆盖
		boolean allCovered = true; // 假设全覆盖
		for (int i = 1; i < isCovered.length; i++)
			if (!isCovered[i]) {
				allCovered = false; //找到1个未覆盖
				break;
			}
		if (allCovered)
			System.out.println("Cover all numbers");
		else
			System.out.println("Don't cover all numbers");
	}
}

编程练习:发扑克牌

编程模拟发扑克牌。

解题思路:

扑克牌共有52张(不含大小王)。首先用一个52个元素的数组表示,并且用0..51的值依次填充数组。约定0..12表示黑桃1..13,13..25表示红桃1..13,26..38表示方块1..13,39..51表示梅花1..13。

接下来,只需要打乱这个数组取前四个,然后根据元素值计算对应的花色,就可以完成发牌过程。

解题思路图示

 

花色计算图示

 

public class DeckOfCards {
	public static void main(String[] args) {
		int[] deck = new int[52];
		String[] suits = { "Spades", "Hearts", "Diamonds","Clubs" };
		String[] ranks = { "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King" };
		//Initialize the cards
		for (int i = 0; i < deck.length; i++)
			deck[i] = i;
		//Shuffle the cards
		for (int i = 0; i < deck.length; i++) {
			//Generate an index randomly
			int index = (int) (Math.random() * deck.length);
			int temp = deck[i];
			deck[i] = deck[index];
			deck[index] = temp;
		}
		//Display the first four cards	
		for (int i = 0; i < 4; i++) {
			String suit = suits[deck[i] / 13];
			String rank = ranks[deck[i] % 13];
			System.out.println("Card number " + deck[i] + ": " + rank + " of " + suit);
		}
	}
}


7.5 Copying Arrays

7.5.1错例:

程序中常常需要把一个数组list1的内容复制给list2,这时候你可能会写出这样的代码: 

list2 = list1;

这个代码不会有编译错,因为它的运行效果是这样:

 

解释一下:上述代码的意思是list2也指向list1数组,后果是list2数组丢失,而list1数组却有两个名字。


7.5.2正确:

要把一个数组复制给另一个数组,需要老老实实用一个循环:

int[] sourceArray = {2, 3, 1, 5, 10};

int[] targetArray = new int[sourceArray.length];

for (int i = 0; i < sourceArrays.length; i++)

   targetArray[i] = sourceArray[i];


7.5.3 arraycopy 工具

实在想偷懒又想复制数组,可以借助System.arraycopy方法:

arraycopy(sourceArray, src_pos, targetArray, tar_pos, length);

Example:

System.arraycopy(sourceArray, 0, targetArray, 0, sourceArray.length);


7.6 Passing Arrays to Methods

数组作为形参,可以有两种方式传递参数

public static void printArray(int[] array) {

  for (int i = 0; i < array.length; i++) {

    System.out.print(array[i] + " ");

  }

}

1、有名数组作为实参

int[] list = {3, 1, 2, 6, 4, 2};

printArray(list);

2、匿名数组作为实参

printArray(new int[]{3, 1, 2, 6, 4, 2});


7.6.1匿名数组

使用下列语法可以创建一个数组:

new dataType[]{literal0, literal1, ..., literalk};

例如这个语句:

printArray(new int[]{3, 1, 2, 6, 4, 2});

由于这种数组并没有指定一个明确的变量名,所以这种数组叫做匿名数组。


7.6.2传值调用

Java中实参与形参之间的数据传递只有一种方式:传值。

对基本数据类型来说,值传递就是把实参的值复制给形参,然后二者就再无关联了。

对非基本数据类型(例如数组、类、接口)来说,值传递也是把实参的值复制给形参,不过此时Java传递的实参值是一个引用(reference),这样造成的结果,就是实参和形参都指向同一个对象。所以针对形参的任何修改,都相当于直接改动实参。

Take the following code, for example:

public class Test {
	public static void main(String[] args) {
		int x = 1; // x represents an int value
		int[] y = new int[10]; // y represents an array of int values
		m(x, y); // Invoke m with arguments x and y
		System.out.println("x is " + x);
		System.out.println("y[0] is " + y[0]);
	}
	public static void m(int number, int[] numbers) {
		number = 1001; // Assign a new value to number
		numbers[0] = 5555; // Assign a new value to numbers[0]
	}
}

x is 1

y[0] is 5555


7.6.3调用栈



执行方法调用m(x, y)时, x 和 y 的值分别复制给 number 和 numbers。 由于 y 是数组,复制的是引用值,因此 numbers 和 y 现在都指向了同一个数组。


当修改形参numbers的某个元素值时,由于numbers和y都指向同一个数组,所以相当于y数组的元素值也被同样修改了。



7.6.4堆(Heap


JVM会把数组存储在一个称为堆( heap )的内存区。这个区域会在JVM的控制下按需自动分配内存,以及在适当的时候自动回收无用内存(未必按照分配的顺序回收)。

继续巩固一下基本数据类型和非基本数据类型(这里是数组)在作为参数传递时的区别。

LISTING 7.3 TestPassArray.java

 public class TestPassArray {
 /** Main method */
	 public static void main(String[] args) {
		 int[] a = {1, 2};

		 // Swap elements using the swap method
		 System.out.println("Before invoking swap");
		 System.out.println("array is {" + a[0] + ", " + a[1] + "}");
		 swap(a[0], a[1]);
		 System.out.println("After invoking swap");
		 System.out.println("array is {" + a[0] + ", " + a[1] + "}");

		 // Swap elements using the swapFirstTwoInArray method
		 System.out.println("Before invoking swapFirstTwoInArray");
		 System.out.println("array is {" + a[0] + ", " + a[1] + "}");
		 swapFirstTwoInArray(a);
		 System.out.println("After invoking swapFirstTwoInArray");
		 System.out.println("array is {" + a[0] + ", " + a[1] + "}");
	 }

	 /** Swap two variables */
	 public static void swap(int n1, int n2) {
		 int temp = n1;
		 n1 = n2;
		 n2 = temp;
	 }

	 /** Swap the first two elements in the array */
	 public static void swapFirstTwoInArray(int[] array) {
		 int temp = array[0];
		 array[0] = array[1];
		 array[1] = temp;
	 }
}

Before invoking swap

array is {1, 2}

After invoking swap

array is {1, 2}

Before invoking swapFirstTwoInArray

array is {1, 2}

After invoking swapFirstTwoInArray

array is {2, 1}

结论就是,两个int作为参数的swap没有完成实参的值的交换,数组作为参数的swapFirstTwoInArray,成功改变了实参的值。


7.7 Returning an Array from a Method

 public static int[] reverse(int[] list) {
	 int[] result = new int[list.length];

	 for (int i = 0, j = result.length - 1;
			 i < list.length; i++, j--) {
		 result[j] = list[i];
	 }

	 return result;
}

Line 2 creates a new array result. Lines 4–7 copy elements from array list to arrayresult. Line 9 returns the array. For example, the following statement returns a new array

list2 with elements 654321.

int[] list1 = {123456};

int[] list2 = reverse(list1);


7.8 Case Study: Counting the Occurrences

of Each Letter

The program given in Listing 7.4 does the following:

1. Generates 100 lowercase letters randomly and assigns them to an array of characters, as shown in Figure 7.7a. You can obtain a random letter by using thegetRandomLower- CaseLetter() method in the RandomCharacter class in Listing 6.10.

2. Count the occurrences of each letter in the array. To do so, create an array, say counts, of 26 int values, each of which counts the occurrences of a letter, as shown in Figure 7.7b. That is, counts[0] counts the number of a’s, counts[1] counts the number of b’s, and so on.

LISTING 7.4 CountLettersInArray.java

 public class CountLettersInArray {
	 /** Main method */
	 public static void main(String[] args) {
		 // Declare and create an array
		 char[] chars = createArray();

		 // Display the array
		 System.out.println("The lowercase letters are:");
		 displayArray(chars);

		 // Count the occurrences of each letter
		 int[] counts = countLetters(chars);

		 // Display counts
		 System.out.println();
		 System.out.println("The occurrences of each letter are:");
		 displayCounts(counts);
	 }

	 /** Create an array of characters */
	 public static char[] createArray() {
		 // Declare an array of characters and create it
		 char[] chars = new char[100];
		 // Create lowercase letters randomly and assign
		 // them to the array
		 for (int i = 0; i < chars.length; i++)
		    chars[i] = RandomCharacter.getRandomLowerCaseLetter();
		 // Return the array
		 return chars;
	 }

	 /** Display the array of characters */
	 public static void displayArray(char[] chars) {
		 // Display the characters in the array 20 on each line
		 for (int i = 0; i < chars.length; i++) {
			 if ((i + 1) % 20 == 0)
				 System.out.println(chars[i]);
			 else
				 System.out.print(chars[i] + " ");
		 }
	 }

	 /** Count the occurrences of each letter */
	 public static int[] countLetters(char[] chars) {
		 // Declare and create an array of 26 int
		 int[] counts = new int[26];

		 // For each lowercase letter in the array, count it
		 for (int i = 0; i < chars.length; i++)
			 counts[chars[i] - 'a']++;

		 return counts;
	 }

	 /** Display counts */
	 public static void displayCounts(int[] counts) {
		 for (int i = 0; i < counts.length; i++) {
			 if ((i + 1) % 10 == 0)
			   System.out.println(counts[i] + " " + (char)(i + 'a'));
			 else
		       System.out.print(counts[i] + " " + (char)(i + 'a') + " ");
		 }
	 }
}

The createArray method (lines 21–32) generates an array of 100 random lowercase letters.

Line 5 invokes the method and assigns the array to chars. What would be wrong if you rewrote the code as follows?

char[] chars = new char[100];

chars = createArray();

    You would be creating two arrays. The first line would create an array by using new char[100].

    The second line would create an array by invoking createArray() and assign the reference of the array to chars. The array created in the first line would be garbage because it is no longer referenced, and as mentioned earlier Java automatically collects garbage behind the scenes.

    Your program would compile and run correctly, but it would create an array unnecessarily. Invoking getRandomLowerCaseLetter() (line 28) returns a random lowercase letter. This method is defined in the RandomCharacter class in Listing 6.10.

    The countLetters method (lines 46–55) returns an array of 26 int values, each of which stores the number of occurrences of a letter. The method processes each letter in the array and increases its count by one. A brute-force approach to count the occurrences of each letter might be as follows:

for (int i = 0; i < chars.length; i++)

if (chars[i] == 'a')

counts[0]++;

else if (chars[i] == 'b')

counts[1]++;

...

But a better solution is given in lines 51–52.

for (int i = 0; i < chars.length; i++)

counts[chars[i] - 'a']++;

    If the letter (chars[i]) is a, the corresponding count is counts['a' - 'a'] (i.e., counts[0]). If the letter is b, the corresponding count is counts['b' - 'a'] (i.e., counts[1]), since the Unicode of is one more than that of a. If the letter is z, the corresponding count is counts['z' - 'a'] (i.e., counts[25]), since the Unicode of is 25 more than that of a.


7.9 Variable-Length Argument Lists

Java treats a variable-length parameter as an array. You can pass an array or a variable number of arguments to a variable-length parameter. When invoking a method with a variable number of arguments, Java creates an array and passes the arguments to it. Listing 7.5 contains a method that prints the maximum value in a list of an unspecified number of values.

LISTING 7.5 VarArgsDemo.java

 public class VarArgsDemo {
	 public static void main(String[] args) {
		 printMax(34, 3, 3, 2, 56.5);
		 printMax(new double[]{1, 2, 3});
	 }

	 public static void printMax(double... numbers) {
		 if (numbers.length == 0) {
			 System.out.println("No argument passed");
		 return;
	 }

	 double result = numbers[0];

	 for (int i = 1; i < numbers.length; i++)
		 if (numbers[i] > result)
			 result = numbers[i];

	 System.out.println("The max value is " + result);
	 }
}

 

7.10 Searching Arrays

数组查找是在数组中查找一个特定的数是否存在,如果存在的话,返回所在下标;如果不存在,返回一个负数(一般是-1,也可以是其它负数,只要不是有效下标就行)

查找有很多方法,这里只讨论其中两个,线性查找 linear search 和二分查找 binary search.


7.10.1 The Linear Search Approach

线性查找是从下标0开始,挨个向后查找指定关键字是否出现。一旦出现后立即退出查找,直接返回下标值;实在找不到的话,返回-1。

线性查找效率较低,编码简单,适用于查找无序的数组。

 

LISTING 7.6 LinearSearch.java

linear search animation on Companion Website List key Compare key with list[i] for i = 0, 1, … [0] [1] [2] …

 public class LinearSearch {
	 /** The method for finding a key in the list */
	 public static int linearSearch(int[] list, int key) {
		 for (int i = 0; i < list.length; i++) {
			 if (key == list[i])
				 return i;
		 }
		 return -1;
	 }
}

To better understand this method, trace it with the following statements:

int[] list = {14425-362};

int i = linearSearch(list, 4); // Returns 1

int j = linearSearch(list, -4); // Returns -1

int k = linearSearch(list, -3); // Returns 5


7.10.2 The Binary Search Approach

如果被查找的数组已经按照升序排列,二分查找是一个更好的选择。例如假设数组是: 2 4 7 10 11 45 50 59 60 66 69 70 79

二分查找首先会定位在数组正中,然后将正中间的元素与关键字做一个比较:

1、如果关键字小于该元素,接下来你只需查找数组前一半;

2、如果二者相等,查找成功结束;

3、如果关键字大于该元素,接下来你只需要查找数组后一半。

/** Use binary search to find the key in the list */
public static int binarySearch(int[] list, int key) {
	int low = 0;
	int high = list.length - 1;
 
  	while (high >= low) {
  		int mid = (low + high) / 2;
  		if (key < list[mid])
  			high = mid - 1;
  		else if (key == list[mid])
  			return mid;
  		else
  			low = mid + 1;
  	}
 	return -1 - low;
}


int[] list = {24710114550596066697079};

Method                 Low  High    Value Returned

binarySearch(list, 2)  0    1           0

binarySearch(list, 11) 3    5           4

binarySearch(list, 12) 5    4          -6

binarySearch(list, 1)  0    -1         -1

binarySearch(list, 3)  1     0         -2


7.10.3 Arrays.binarySearch方法

Java的数组工具类提供了多个版本的 binarySearch供调用,支持对已经按照升序排列的int, double, char, short, long, float数组进行二分查找。

例如:

int[] list = {2, 4, 7, 10, 11, 45, 50, 59, 60, 66, 69, 70, 79};

System.out.println("Index is " + java.util.Arrays.binarySearch(list, 11)); //返回4,查找成功

char[] chars = {'a', 'c', 'g', 'x', 'y', 'z'};

System.out.println("Index is " +java.util.Arrays.binarySearch(chars, 't')); //返回-4,查找失败


7.11 Sorting Arrays

排序是数组的常见任务。更多的排序算法在《数据结构》课程里介绍,这里只介绍两个简单的排序算法:选择排序(selection sort )和插入排序(insertion sort)。


7.11.1选择排序

选择排序的算法是:每次选取一个数组的最小值,并把它交换到数组的最前面。下图是数组 {2, 9, 5, 4, 8, 1, 6}的排序过程。


for (int i = 0; i < list.length; i++)

{

   在 list[i..listSize-1]中找最小值;

   如果必要的话,把最小值交换到list[i];

   // list[i]排序完毕

   // 下一步要排序list[i+1..listSize-1]

}

LISTING 7.8 SelectionSort.java

public static void selectionSort(double[] list) {
	for (int i = 0; i < list.length; i++) {
      // Find the minimum in the list[i..list.length-1]
		double currentMin = list[i];
		int currentMinIndex = i;
		for (int j = i + 1; j < list.length; j++) {
			if (currentMin > list[j]) {
				currentMin = list[j];
				currentMinIndex = j;
			}
		}
		// Swap list[i] with list[currentMinIndex] if necessary;
		if (currentMinIndex != i) {
			list[currentMinIndex] = list[i];
			list[i] = currentMin;
		}
	}
}


7.11.2 插入排序

算法的思想是每次在一个有序的列表中,新插入一个尚未排序的元素,让新的列表继续保持有序,直到整个数组插入完毕。

int[] myList = {2, 9, 5, 4, 8, 1, 6}; // 无序


插入新元素的思路是,让元素从列表的最后一个元素往前移动,直到无法移动为止。


for (int i = 1; 1; i < list.length; i++) {

   list[i]元素插入已排序的list[0..i-1]中,并保持有序

   于是list[0..i]排序完毕

}

public static void insertionSort(double[] list) {
	for (int i = 1; i < list.length; i++) {
    /** Insert list[i] into a sorted sublist list[0..i-1] so that list[0..i] is sorted. */
		double currentElement = list[i];
		int k;
        for (k = i - 1; k >= 0 && list[k] > currentElement; k--) {
            list[k + 1] = list[k];
        }
        // Insert the current element into list[k + 1]
        list[k + 1] = currentElement;
    }
}


7.11.3 Arrays.sort方法

Java的数组工具类提供了多个版本的sort供调用,支持对int, double, char, short, long, float数组进行排序,例如:

double[] numbers = {6.0, 4.4, 1.9, 2.9, 3.4, 3.5};

java.util.Arrays.sort(numbers);

char[] chars = {'a', 'A', '4', 'F', 'D', 'P'};

java.util.Arrays.sort(chars);


7.12 The Arrays Class

The java.util.Arrays class contains various static methods for sorting and searching arrays, comparing arrays, filling array elements, and returning a string representation of the array. These methods are overloaded for all primitive types. You can use the sort or parallelSort method to sort a whole array or a partial array.

For example, the following code sorts an array of numbers and an array of characters.

double[] numbers = {6.04.41.92.93.43.5};

java.util.Arrays.sort(numbers); // Sort the whole array

java.util.Arrays.parallelSort(numbers);//Sort the whole array

char[] chars = {'a''A''4''F''D''P'};

java.util.Arrays.sort(chars, 13); // Sort part of the array

java.util.Arrays.parallelSort(chars, 13); //Sort part of the array

Invoking sort(numbers) sorts the whole array numbers. Invoking sort(chars, 1, 3) sorts a partial array from chars[1] to chars[3-1]parallelSort is more efficient if your computer has multiple processors.

You can use the binarySearch method to search for a key in an array. The array must be presorted in increasing order. If the key is not in the array, the method returns –(insertionIndex + 1). For example, the following code searches the keys in an array of integers and an array of characters.

int[] list = {24710114550596066697079};

System.out.println("1. Index is " + java.util.Arrays.binarySearch(list, 11));

System.out.println("2. Index is " + java.util.Arrays.binarySearch(list, 12));

char[] chars = {'a''c''g''x''y''z'};

System.out.println("3. Index is " + java.util.Arrays.binarySearch(chars, 'a'));

System.out.println("4. Index is " + java.util.Arrays.binarySearch(chars, 't'));

The output of the preceding code is

1. Index is 4

2. Index is -6

3. Index is 0

4. Index is -4

 

You can use the equals method to check whether two arrays are strictly equal. Two arrays are strictly equal if their corresponding elements are the same. In the following code, list1 and list2 are equal, but list2 and list3 are not.

int[] list1 = {24710};

int[] list2 = {24710};

int[] list3 = {42710};

System.out.println(java.util.Arrays.equals(list1, list2)); // true

System.out.println(java.util.Arrays.equals(list2, list3)); // false

You can use the fill method to fill in all or part of the array. For example, the following code fills list1 with and fills into elements list2[1] through list2[5-1].

int[] list1 = {24710};

int[] list2 = {2477710};

java.util.Arrays.fill(list1, 5); // Fill 5 to the whole array

java.util.Arrays.fill(list2, 158); // Fill 8 to a partial array

You can also use the toString method to return a string that represents all elements in the array. This is a quick and simple way to display all elements in the array. For example, the following code

int[] list = {24710};

System.out.println(Arrays.toString(list));

displays [2, 4, 7, 10].

 

7.13 Command-Line Arguments

Java的main函数有个形参args,用于接收命令行参数。例如下面的代码:

 

运行:java TestMain "First num" alpha 53

则args.length为3,3个元素分别为First num,alpha,53。

 

7.13.1 Passing Strings to the main Method

You can pass strings to a main method from the command line when you run the program. The following command line, for example, starts the program TestMain with three strings:

arg0arg1, and arg2:

java TestMain arg0 arg1 arg2

arg0arg1, and arg2 are strings, but they don’t have to appear in double quotes on the command line. The strings are separated by a space. A string that contains a space must be enclosed in double quotes. Consider the following command line:

java TestMain "First num" alpha 53

It starts the program with three strings: First num, alpha, and 53. Since First num is a string, it is enclosed in double quotes. Note that 53 is actually treated as a string. You can use "53" instead of 53 in the command line. When the main method is invoked, the Java interpreter creates an array to hold the command- line arguments and pass the array reference to args. For example, if you invoke a program with arguments, the Java interpreter creates an array like this one:

args = new String[n];

The Java interpreter then passes args to invoke the main method.

Note

If you run the program with no strings passed, the array is created with new String[0]. In this case, the array is empty with length 0args references to this empty array. Therefore, args is not null, but args.length is 0.


7.13.2 Case Study: Calculator

写一个命令行计算器,支持从参数中读取表达式并计算。输入格式如下:

java Calculator 2 + 3

输出格式如下:

2 + 3 = 5

其中两个数与运算符之间都有空格,运算符有+-./四种。因为*有特殊含义(表示当前目录下所有文件),这里用.代替。

LISTING 7.9 Calculator.java

 public class Calculator {
	 /** Main method */
	 public static void main(String[] args) {
		 // Check number of strings passed
		 if (args.length != 3) {
			 System.out.println(
				 "Usage: java Calculator operand1 operator operand2");
			 System.exit(0);
		 }
		 // The result of the operation
		 int result = 0;

		 // Determine the operator
		 switch (args[1].charAt(0)) {
			 case '+': result = Integer.parseInt(args[0]) +
				 Integer.parseInt(args[2]);
			 break;
			 case '-': result = Integer.parseInt(args[0]) -
				 Integer.parseInt(args[2]);
			 break;
			 case '.': result = Integer.parseInt(args[0]) *
				 Integer.parseInt(args[2]);
			 break;
			 case '/': result = Integer.parseInt(args[0]) /
				 Integer.parseInt(args[2]);
		 }

		 // Display result
		 System.out.println(args[0] + ' ' + args[1] + ' ' + args[2]
				 + " = " + result);
	 }
}


CHAPTER SUMMARY

1. A variable is declared as an array type using the syntax elementType[] arrayRefVar

or elementType arrayRefVar[]. The style elementType[] arrayRefVar is preferred, although elementType arrayRefVar[] is legal.

2. Unlike declarations for primitive data type variables, the declaration of an array variable does not allocate any space in memory for the array. An array variable is not a primitive data type variable. An array variable contains a reference to an array.

3. You cannot assign elements to an array unless it has already been created. You can create an array by using the new operator with the following syntax:new elementType[arraySize].

4. Each element in the array is represented using the syntax arrayRefVar[index]. An index must be an integer or an integer expression.

5. After an array is created, its size becomes permanent and can be obtained using arrayRefVar.length. Since the index of an array always begins with 0, the last index is always arrayRefVar.length - 1. An out-of-bounds error will occur if you attempt to reference elements beyond the bounds of an array.

6. Programmers often mistakenly reference the first element in an array with index 1, but it should be 0. This is called the index off-by-one error.

7. When an array is created, its elements are assigned the default value of for the numeric primitive data types, \u0000 for char types, and false for boolean types.

8. Java has a shorthand notation, known as the array initializer, which combines declaring an array, creating an array, and initializing an array in one statement, using the syntax elementType[] arrayRefVar = {value0, value1, ..., valuek}.

9. When you pass an array argument to a method, you are actually passing the reference of the array; that is, the called method can modify the elements in the caller’s original array.

10. If an array is sorted, binary search is more efficient than linear search for finding an element in the array.

11. Selection sort finds the smallest number in the list and swaps it with the first element. It then finds the smallest number remaining and swaps it with the first element in the remaining list, and so on, until only a single number remains.

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值