Java-Chapter 7 Single-Dimensional Arrays

问题 1:如何声明一个数组变量?

答案
可以使用以下两种语法声明数组变量:

  1. elementType[] arrayRefVar(推荐样式)。
  2. elementType arrayRefVar[](合法但不推荐)。

解释

  • elementType 是数组中每个元素的类型,例如 intdouble 等。
  • arrayRefVar 是数组变量的名称。
  • 推荐使用 elementType[] arrayRefVar,因为它将数组类型和变量分开,更清晰。

示例

1
2
int[] numbers;  // 推荐
int numbers[]; // 合法但不推荐

问题 2:数组变量的声明和数组的创建有什么区别?

答案
数组变量的声明仅定义一个引用,不会为数组分配内存。数组的创建需要使用 new 操作符分配内存。

解释

  • 声明数组变量只表示它是一个引用,但不包含任何实际数据。
  • 只有通过 new elementType[arraySize] 才会分配内存,创建数组。
  • 声明和创建可以分开,也可以组合。

示例

1
2
3
4
5
int[] numbers;          // 声明数组变量,未分配内存
numbers = new int[10]; // 创建一个包含 10 个元素的数组

// 声明和创建结合
int[] numbers2 = new int[5];

问题 3:数组的元素存储在哪里?

答案
数组的元素存储在堆内存(heap)中,这是一块可以动态分配的内存区域。

解释

  • 数组是引用类型,其实际数据存储在堆内存中,而引用本身存储在栈内存中。
  • 堆内存允许动态分配,数组可以在程序运行时根据需求分配。

示例

1
int[] numbers = new int[3];  // 堆内存分配了存储 3 个整数的空间

问题 4:如何访问数组的元素?

答案
通过 arrayRefVar[index] 访问数组元素,其中 index 是数组的下标,从 0 开始。

解释

  • 数组的下标必须是整数或整数表达式。
  • 下标从 0 开始,arrayRefVar[0] 表示第一个元素。
  • 访问超出范围的下标会导致运行时错误 ArrayIndexOutOfBoundsException

示例

1
2
3
4
5
6
int[] numbers = {10, 20, 30};
System.out.println(numbers[0]); // 输出:10
System.out.println(numbers[2]); // 输出:30

// 错误示例:访问超出范围的下标
System.out.println(numbers[3]); // 抛出 ArrayIndexOutOfBoundsException

问题 5:如何获取数组的大小?

答案
通过 arrayRefVar.length 获取数组的大小。

解释

  • length 是数组的属性,返回数组的元素数量。
  • 数组的索引从 0 开始,因此最后一个元素的索引是 arrayRefVar.length - 1
  • 如果访问超出范围的索引,将抛出 ArrayIndexOutOfBoundsException

示例

1
2
3
4
int[] numbers = {1, 2, 3, 4};
System.out.println(numbers.length); // 输出:4
System.out.println(numbers[3]); // 输出:4
System.out.println(numbers[4]); // 抛出 ArrayIndexOutOfBoundsException

问题 6:数组默认值是什么?

答案

  • 数字类型(如 intdouble):默认值为 0
  • 字符类型(char):默认值为 '\u0000'(空字符)
  • 布尔类型(boolean):默认值为 false
  • 引用类型(如 String):默认值为 null

解释
当创建数组但未对元素初始化时,所有元素会被自动赋予各自类型的默认值。

示例

1
2
3
4
5
6
7
8
int[] numbers = new int[3];          // 创建长度为 3 的 int 数组
System.out.println(numbers[0]); // 输出:0

boolean[] flags = new boolean[2];
System.out.println(flags[1]); // 输出:false

char[] chars = new char[1];
System.out.println(chars[0] == '\u0000'); // 输出:true

问题 7:如何用数组初始化器快速初始化数组?

答案
使用 数组初始化器elementType[] arrayRefVar = {value0, value1, ..., valuek}

解释

  • 数组初始化器是声明、创建和初始化数组的快捷方式。
  • 不需要显式调用 new 来创建数组,编译器会自动完成。

示例

1
2
int[] numbers = {1, 2, 3, 4};  // 使用数组初始化器
System.out.println(numbers[2]); // 输出:3

问题 8:将数组作为参数传递时会发生什么?

答案
传递的是数组的引用(即指向数组的内存地址)。
因此,被调用的方法可以直接修改原始数组的内容。

解释

  • Java 使用的是引用传递,但不改变引用本身,只能通过引用修改数组的内容。
  • 这种特性使得数组在方法中被修改会影响到调用者的数组。

示例

1
2
3
4
5
6
7
8
9
10
11
public class Main {
public static void main(String[] args) {
int[] numbers = {1, 2, 3};
modifyArray(numbers);
System.out.println(numbers[0]); // 输出:10
}

public static void modifyArray(int[] array) {
array[0] = 10; // 修改原数组的第一个元素
}
}

问题 9:如何使用选择排序和插入排序对数组排序?

答案

  • 选择排序(Selection Sort):每次找到剩余未排序部分的最小元素并将其移到开头。
  • 插入排序(Insertion Sort):逐步将元素插入到前面已经排序好的子数组中。

解释

  • 选择排序适合数据量较小的场景,时间复杂度为 O(n²),空间复杂度为 O(1)
  • 插入排序对几乎已排序的数组效率较高,时间复杂度平均为 O(n²),最优情况下为 O(n)

问题 10:如何使用 java.util.Arrays 对数组进行操作?

答案
java.util.Arrays 提供静态方法,可用于排序、查找和比较数组。

  1. 排序数组
    使用 Arrays.sort 方法对数组进行排序:

    1
    2
    3
    int[] numbers = {4, 2, 5, 1};
    java.util.Arrays.sort(numbers);
    System.out.println(java.util.Arrays.toString(numbers)); // 输出:[1, 2, 4, 5]
    • 支持部分排序Arrays.sort(array, fromIndex, toIndex)
  2. 二分查找
    使用 Arrays.binarySearch 在排序数组中查找元素:

    1
    2
    3
    int[] numbers = {1, 2, 4, 5};
    int index = java.util.Arrays.binarySearch(numbers, 4);
    System.out.println(index); // 输出:2
    • 若找不到元素,返回 -插入点 - 1
    • 插入点是元素应当插入的位置索引。

问题 11:binarySearch 返回值的意义是什么?

答案

  1. 如果 key 存在:返回它的索引。
  2. 如果 key 不存在:返回 -插入点 - 1,表示插入点的负值减 1。

解释

  • 插入点:是数组中第一个大于 key 的位置。
  • 返回负值可以快速区分是否找到目标值。

示例

1
2
3
int[] numbers = {1, 2, 4, 5};
System.out.println(java.util.Arrays.binarySearch(numbers, 3)); // 输出:-3
System.out.println(java.util.Arrays.binarySearch(numbers, 4)); // 输出:2

解析

  • 查找 3,插入点是索引 2,返回 -2 - 1 = -3
  • 查找 4,返回其索引 2

问题 12:Arrays.sortArrays.binarySearch 的使用限制?

答案

  1. Arrays.sort
    • 只能用于数组,而不能用于集合(如 ArrayList)。
    • 对于部分排序,fromIndextoIndex 必须在合法范围内,否则抛出异常。
  2. Arrays.binarySearch
    • 必须作用于已排序数组。若未排序,结果可能不正确。