[Java] 一维数组

1 数组的声明和创建

语法为:
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;

2 处理数组

  1. 用输入值初始化数组
  2. 用随机值初始化数组
  3. 显示数组
  4. 所有元素求和
  5. 寻找最大的元素
  6. 寻找最大元素的最小索引
  7. 随机洗牌
  8. 移动元素
  9. 简化代码

例子:打印大于平均数的个数

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);
    }
}

3. 复制数组

复制数组不能直接变量划等号:

double[] list1 = {1, 2, 3};
double[] list2 = {4, 5, 6};
list2 = list1;  // Cannot copy array!

list2 = list1的结果就是,list1list2都引用相同的数组,list2原先引用的数组变为垃圾,将由JVM自动回收。如此赋值不能实现数组复制。
实现数组复制有3种方法:

1. 数组元素逐个复制

2. 使用System类中的静态arraycopy方法:
arraycopy(sourceArray, srcPos, targetArray, tarPos, length);

3. 使用clone方法(涉及到抽象类和接口)

4. 将数组传递给方法

当传递数组给方法时,实际传递的是数组的引用。

匿名数组

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将对象存在堆内存中。

5. 从方法返回数组

当方法返回数组时,返回的实际上是数组的引用。
反转数组的一个例子:

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 秒)

6. 可变长度参数列表

相同类型的可变数目的参数可以传给方法,并看作一个数组。
方法的可变长度参数声明形式为: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 秒)

7. 数组查找

介绍了两种,线性查找和二进制查找,线性查找直观,二进制要先排序,但查找速度快。

8. 数组排序

选择排序算法,省略

9. Array

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).使用二进制查找之前,数组必须先以递增的顺序排序过,如果失败则返回 –(insertionIndex + 1) (这个变量是什么?)

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]

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
如果没有参数,argsnull, 但 args.length 为 0.

书上还有计算器的实现例子,先省略。


[1] Introduction to Java Programming 10th. chapter 7.

猜你喜欢

转载自blog.csdn.net/ftell/article/details/80452378