首先思考一个问题,我们这么多人是如何整理在一起上课的?
分了班级?对不对。所以我们一大帮子人进行集中、整理、放置在一起,就形成了一个“班级”。那么当出现了很多的数据呢?
数据,也可以像我们每一个人一样,集中合并放置在一起,进行批量存储和操作。数组就是集合当中最原始最简单的一种。
在 java 中,数组的特点在于:

  1. 只能存放同一数据类型的数据
  2. 所有元素数据存放在连续内存空间
  3. 数组空间大小一旦确定,不可更改

这三个特点也是 java 中数组的缺点,但由于数组的不可被修改性,后面我们还会学习其他的数据结构。

声明方式

声明方式存在两种

  • 明确数据情况
  • 未知具体数据情况,仅知道元素个数

    明确数据情况

    这种声明方式适合于明确数组中数据的值。
    语法:元素类型 [] 数组名称 = {数据1, 数据2, ... 数据n}; ```java // 表示内存中开辟了一块空间用于存储 5 个整数 int [] numbers = {1, 2, 3, 4, 5};

// 表示内存中开辟了一块空间用于存储 3 个浮点数,56 也会被存储为 56.0 double [] rainFall = {12.3, 78.4, 56};

// 表示内存中开辟了一块空间用于存储 4 个字符串 String[] users = {“zhangsan”, “lisi”, “wangwu”, “zhaoliu”};

  1. 对于数组(变量)名 numbersrainFallusers 都是一个引用,指向了内存中的地址,以便我们对数组进行操作。
  2. <a name="YoeEg"></a>
  3. ### 未知数据情况
  4. 这种方式适用于不确定数组中值,只明确存放的个数。<br />语法:`数据类型 [] 数组名称 = new 数据类型[数组长度];`
  5. ```java
  6. // 声明了一个名为 numbers 长度为 8 的数组,用于未来存放整数
  7. int [] numbers = new int[8];
  8. // 声明了一个名为 rainFall 长度为 10 的数组,用于未来存放小数
  9. double[] rainFall = new double[10];

存放方式

当书写完数组的声明后,它在内存中的存放方式实际上是一个引用,通过变量名字 “numbers”、“rainFall”、“users” 指向了一块内存地址。
像之前我们书写的 int a = 5;char c = 'c'; 5 和字符 c 都是属于基本数据类型,对吧?基本数据类型的变量空间中存放的是值本身,引用类型的变量空间中存放的是引用,该引用指向真正的数据。
4.png
总结下来就是:

  • 基本数据类型的变量空间中存放的是值本身
  • 引用类型的变量空间中存放的是引用,该引用指向真正的数据

    默认初始化值

    在对于第二种只明确个数的声明方式 int[] numbers = new int[8] 每个元素会默认初始化为 0。
    5.png
  1. 若元素是基本数据类型,赋值初始化为 0
    • int 类型,各元素初始化为 0
    • double/float 类型,各元素初始化为 0.0
    • char 类型,各元素初始化为 ASCII 码为 0 的字符(一个空字符)
    • boolean 类型,各元素初始化为 false
  2. 若元素为引用数据类型,赋值初始值为 null
    1. int [] numbers = new int[10]; // 访问 numbers[0] 得到 0
    2. double [] rainFall = new double[5]; // 访问 rainFall[0] 得到 0.0
    3. String[] names = new String[5];// 访问 names[0] 得到 null

    操作数组中的元素

    数组中的元素通过 数组名[下标] 进行操作。下标相当于元素在数组中的编号,下标从 0 开始,最大下标为数组长度减1。
    6.png
    若下标不在范围,会报异常:ArrayIndexOutOfBoundsException 即(数组下标越界异常)。数组有一个 length 属性用来代表数组的长度,可以避免数据访问时越界。 ```java int numbers[] = {1, 2, 3, 4, 5}; System.out.println(numbers[886]); // ArrayIndexOutOfBoundsException: Index 886 out of bounds for length 5

System.out.println(numbers.length); // 5

  1. <a name="ILXad"></a>
  2. ## 遍历数组
  3. 遍历数组就是指依次拿到数组中的每一个元素,进行相应的操作。我们已知数组下标从 0 开始,所以可以使用循环取得数组中每一项。
  4. ```java
  5. for(int i = 0; i < arr.length; i++){
  6. // 相应操作
  7. }

数组的拷贝

我们已经得知数组是属于引用类型的,数组变量名只是一个引用:

  1. int arr1[] = {1, 2, 3};
  2. int arr2[] = arr1; // arr1 和 arr2 指向了同一块内存空间
  3. arr1[0] = 886; // 其中一个被改变
  4. System.out.println(arr2[0]); // 另一个也同时被改变

为了使两块内存空间独立开来,就需要对“数据”进行拷贝。尝试对 int arr[] = {1, 2, 3};进行拷贝。

排序

对集合中元素进行排序也是非常常用基本操作。排序的方式有很多,冒泡、选择、自然等等,语言自带了排序方法,对于手写排序,主要掌握冒泡或者选择排序。

  1. /*
  2. 选择排序
  3. 数组中一个数和后面所有数字一一比较
  4. */
  5. int arr[] = {3, 15, 6, 2, 8, 19};
  6. for (int i = 0; i < arr.length; i++) {
  7. for (int j = i + 1; j < arr.length; j++) {
  8. if (arr[i] > arr[j]) {
  9. int temp = arr[i];
  10. arr[i] = arr[j];
  11. arr[j] = temp;
  12. }
  13. }
  14. }
  1. /*
  2. 冒泡排序
  3. 数组中的数字两两比较
  4. */
  5. for (int count = 1; count < arr.length; count++) {
  6. for (int i = 0; i < arr.length - 1; i++) {
  7. if (arr[i] > arr[i + 1]) {
  8. int temp = arr[i];
  9. arr[i] = arr[i + 1];
  10. arr[i + 1] = temp;
  11. }
  12. }
  13. }
  14. for (int i = 0; i < arr.length; i++) {
  15. System.out.println(arr[i]);
  16. }