语法为: elementType[] arrayRefVar;
例如: int[] myList;
写成与C/C++兼容的形式int myList[]
也是可以的, 但在Java中写成int[] myList
是首选。
// 声明数组变量 myList, 创建数组,并将数组引用赋给变量 double[] myList = new double[10];
声明,创建以及初始化3合1,语法: elementType[] arrayRefVar = {value0, value1, ..., valuek};
例子: 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;
- 用输入值初始化数组
- 用随机值初始化数组
- 显示数组
- 所有元素求和
- 寻找最大的元素
- 寻找最大元素的最小索引
- 随机洗牌
- 移动元素
- 简化代码
package testarray; public class TestArray { public static void main(String[] args) { java.util.Scanner Input = new java.util.Scanner(System.in); System.out.print("Enter the number of items: "); int n = Input.nextInt(); double[] numbers = new double[n]; int counts = 0; double sum = 0; System.out.print("Enter these numbers: "); for (int i = 0; i < n; i++) { numbers[i] = Input.nextDouble(); sum += numbers[i]; } double average = sum / n; for (int i = 0; i < n; i++) { if (numbers[i] > average) counts++; } System.out.println("The average is: " + average); System.out.println("The number of items above average is " + counts); } }
复制数组不能直接变量划等号:
double[] list1 = {1, 2, 3}; double[] list2 = {4, 5, 6}; list2 = list1; // Cannot copy array!
list2 = list1
的结果就是,list1
和 list2
都引用相同的数组,list2
原先引用的数组变为垃圾,将由JVM自动回收。如此赋值不能实现数组复制。
实现数组复制有3种方法:
1. 数组元素逐个复制
2. 使用System
类中的静态arraycopy
方法: arraycopy(sourceArray, srcPos, targetArray, tarPos, length);
3. 使用clone
方法(涉及到抽象类和接口)
当传递数组给方法时,实际传递的是数组的引用。
public static void printArray(int[] array) { for (int i = 0; i < array.length; i++) { System.out.print(array[i] + " "); } }
调用该方法时,可以使用: printArray(new int[] {1, 2, 3, 4, 5});
使用语法new elementType[]{value0, value1, ..., valuek}
创建的数组叫做匿名数组。
Java 使用 pass-by-value
的方式传递参数给方法,传递原生数据类型的值和传递数组之间有着重要的区别:
1. 对于原生类型参数,传递参数的值
2. 对于数组类型参数,参数的值为对数组的引用,此引用值被传递给方法。语义上说,最好描述为 pass-by-sharing, 也就是说,方法中的数组同被传递的数组,因此,如果在方法中改变数组,你可以看到在方法外的数组也被修改了。
Java 中,数组是对象,JVM将对象存在堆内存中。
当方法返回数组时,返回的实际上是数组的引用。
反转数组的一个例子:
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; }
对这个方法的调用如下:
int[] list1 = {1, 2, 3, 4, 5, 6}; int[] list2 = reverse(list1);
给定一个随机字符的数组,长度100, 统计每个字母出现的次数:
// FILENAME: RandomCharacter.java /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package testarray; /** * * @author */ public class RandomCharacter { /** Generate a random character between ch1 and ch2 */ public static char getRandomCharacter(char ch1, char ch2) { return (char)(ch1 + Math.random() * (ch2 - ch1 + 1)); } /** Generate a random lowercase letter */ public static char getRandomLowerCaseLetter() { return getRandomCharacter('a', 'z'); } /** Generate a random uppercase letter */ public static char getRandomUpperCaseLetter() { return getRandomCharacter('A', 'Z'); } /** Generate a random digit character */ public static char getRandomDigitCharacter() { return getRandomCharacter('0', '9'); } /** Generate a random character */ public static char getRandomCharacter() { return getRandomCharacter('\u0000', '\uFFFF'); } }
// FILENAME: TestArray.java * * To change this template, choose Tools | Templates * and open the template in the editor. */ package testarray; public class TestArray { 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 lowercase letters are: x l w s j e p k n k c t b t c j e c u y l j r k j j c i o c k s n t i d p a a v y o a b y p a w o f i a w t z d r c h a a j o g e g q m w w o g d u p g x u m z j q c m j p a w n k i t s q s t c g l u The occurrences of each letter are: 8 a 2 b 8 c 3 d 3 e 1 f 5 g 1 h 4 i 8 j 5 k 3 l 3 m 3 n 5 o 5 p 3 q 2 r 4 s 6 t 4 u 1 v 6 w 2 x 3 y 2 z 成功生成(总时间:0 秒)
相同类型的可变数目的参数可以传给方法,并看作一个数组。
方法的可变长度参数声明形式为:typeName... parameterName
例如:public static void printMax(double... numbers)
, 一个方法里最多只能有一个可变长度的参数,而且必须是最后一个参数,一般的参数排列靠前。
输出最大值的例子:
package testarray; public class TestArray { public static void main(String[] args) { printMax(34, 3, 3, 2, 56.5); printMax(new double[]{1, 2, 3}); printMax(1, 2, 2, 1, 4); printMax(new double[]{1, 2, 3}); //printMax(new int[]{1, 2, 3}); // 错误:required double[], found int[] } 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); } }
输出:
run: The max value is 56.5 The max value is 3.0 The max value is 4.0 The max value is 3.0 成功生成(总时间:0 秒)
介绍了两种,线性查找和二进制查找,线性查找直观,二进制要先排序,但查找速度快。
选择排序算法,省略
java.util.Arrays
类含有用于一般数组操作的有用方法:例如排序和查找
使用语句: import java.util.Arrays;
(1).对数组排序,可以对整个数组排序,也可以只对部分数组排序。如果电脑有多个处理器的话,使用parallelSort
效率会更高。
double[] numbers = {6.0, 4.4, 1.9, 2.9, 3.4, 3.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, 1, 3); // Sort part of the array: 1 ~ 3-1 java.util.Arrays.parallelSort(chars, 1, 3); // Sort part of the array
(2).使用二进制查找之前,数组必须先以递增的顺序排序过,如果失败则返回 (这个变量是什么?)
int[] list = {2, 4, 7, 10, 11, 45, 50, 59, 60, 66, 69, 70, 79}; 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'));
(3).使用equals
方法检查两个数组是否相同,
int[] list1 = {2, 4, 7, 10}; int[] list2 = {2, 4, 7, 10}; int[] list3 = {4, 2, 7, 10}; System.out.println(java.util.Arrays.equals(list1, list2)); // true System.out.println(java.util.Arrays.equals(list2, list3)); // false
(4).使用fill
方法填充数组:
int[] list1 = {2, 4, 7, 10}; int[] list2 = {2, 4, 7, 7, 7, 10}; java.util.Arrays.fill(list1, 5); // Fill 5 to the whole array java.util.Arrays.fill(list2, 1, 5, 8); // Fill 8 to a partial array: 1 ~ 5-1
(5).使用toString
方法返回数组所有元素的字符串表示:
int[] list = {2, 4, 7, 10}; System.out.println(Arrays.toString(list)); // 输出: [2, 4, 7, 10]
main方法可从命令行接收字符串参数 main
方法可以像一般方法一样被调用, 下例中,class A
调用了class TestMain
中的main
函数:
// Part 1 public class TestMain { public static void main(String[] args) { for (int i = 0; i < args.length; i++) System.out.println(args[i]); } }
// Part 2 public class A { public static void main(String[] args) { String[] strings = {"New York", "Boston", "Atlanta"}; TestMain.main(strings); } }
可以从命令行传参数给main
方法,格式如: java TestMain arg0 arg1 arg2
参数如果不是有空格,则不必加双引号: java TestMain "First num" alpha 53
当main
方法被调用时,Java 解释器创建数组存储命令行参数,并将引用传给args
。
如果没有参数,args
非null
, 但 args.length
Ϊ 0.
书上还有计算器的实现例子,先省略。
[1] Introduction to Java Programming 10th. chapter 7.