【JavaSE基础笔记 · 坤】Java数组

由 MisakaStone 发布

1 数组概述

数组是相同类型数据的有序集合。

数组描述的是相同类型的若干个数据,按照一定的先后次序组合而成。

其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们。

数组的四个基本特点

  1. 数组长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
  2. 数组的元素必须是相同数据类型,不允许出现混合类型。
  3. 数组中的元素可以是任何数据类型,包括基本类型引用类型
  4. 数组变量属于引用类型,也可以将数组看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象存储在中,因此数组无论保存的是原始类型还是其他对象类型,数组对象本身是在堆中的

2 数组的声明与创建

首先必须声明数组变量,才能在程序中使用数组。

下面是声明数组变量的语法:

dataType[] arrayRefVar; // java首选声明方法 
dataType arrayRefVar[]; // C/C++风格声明方法

Java语言使用new操作符来创建数组,语法如下:

dataType[] arrayRefVar = new dataType[arraySize];

数组的元素是通过索引访问的,数组索引从0开始。

获取数组长度:

arrays.length

3 内存分析

  • Java内存

      • 存放new的对象和数组
      • 可以被所有的线程共享,不会存放别的对象引用
      • 存放基本变量类型(会包含这个基本类型的具体数值)
      • 引用对象的变量(会存放这个引用在堆里面的具体地址)
    • 方法区

      • 可以被所有的线程共享
      • 都包含了所有的class和static变量

4 三种初始化

首先定义类Human,参数为性别年龄,均为整数类型。

public class Human {

    int gender;
    int age;

    //含参构造器
    public Human(int genderKey, int ageKey) {
        gender = genderKey;
        age = ageKey;
    }

}

静态初始化

int[] intArray = {1, 2, 3};
Human[] humans = {new Human(0, 18), new Human(1, 20)};

动态初始化

int[] array = new int[3];
array[0] = 1;
array[1] = 2;
array[2] = 3;

数组的默认初始化

数组是引用类型,它的元素相当于类的实例变量,因此数组一经空间分配,其中的每个元素也会被按照实例变量同样的方式被隐式初始化。

整形数组中未被定义的元素默认值为0。


5 数组边界

下标的合法区间:[0, length - 1]

如果越界就会报错:

int[] array = new int[3];
System.out.println(array[3]);

运行之,

下标越界异常

java.lang.ArrayIndexOutOfBoundsException 数组下标越界异常

小结:

  • 数组是相同数据类型(数据类型可以为任意类型)的有序集合。
  • 数组是对象,数组元素相当于对象的成员变量。
  • 数组长度是确定的,不可变的。如果下标越界则报:ArrayIndexOutOfBounds

6 数组的使用

四种简单的使用方法:

  • 普通for循环
  • for-each循环
  • 数组作方法参数
  • 数组作方法返回值

反转数组

反转数组方法:

public static int[] reverse(int[] originalArray) { 
    int[] reversedArray = new int[originalArray.length];
    for (int i = 0; i < originalArray.length; i ++) {
        reversedArray[originalArray.length - i - 1] = originalArray[i];
    }
    return reversedArray;
}

输出数组元素:

public static void print(int[] array) {
    for (int i : array) {
        System.out.print(i + "\t");
    }
    System.out.println();
}

测试之:

反转数组


7 多维数组

多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其中每个元素都是一个一维数组。

二维数组定义举例:

int array[][] = new int[2][3];

8 Arrays类详解

数组工具类:java.util.Arrays

虽然数组对象本身没啥方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作。

可以通过查看JDK帮助文档来了解Arrays类相关方法。

Arrays类中的方法都是static修饰的静态方法,在使用时可以直接使用类名进行调用,不用使用对象来调用。

常用功能:

  • fill方法赋值
  • sort方法升序排序
  • equals方法比较元素是否相等
  • binarySearch方法二分查找数组元素
int[] array1 = {0, 10, 100, 22, 33};

System.out.println(Arrays.toString(array1) + "\n");

// 升序排序
Arrays.sort(array1);
System.out.println(Arrays.toString(array1) + "\n");

// 二分查找
System.out.println(Arrays.binarySearch(array1, 50));
System.out.println(Arrays.binarySearch(array1, 33));
System.out.println(Arrays.binarySearch(array1, 1, 4, 22) + "\n");

// 自动填充
Arrays.fill(array1, 1, 4, 999 );
System.out.println(Arrays.toString(array1) + "\n");

// 元素比较
int[] array2 = {1, 999, 999, 999, 1}; // array1 : 0, 999, 999, 999, 100
System.out.println(Arrays.equals(array1, array2));
System.out.println(Arrays.equals(array1, 1, 4, array2, 1, 4) + "\n");

输出为:

[0, 10, 100, 22, 33]

[0, 10, 22, 33, 100]

-5
3
2

[0, 999, 999, 999, 100]

false
true

在二分查找方法中,参数数组中的元素必须为升序排列的元素,查找成功返回元素下标,不成功则返回插入位置下标加一的相反数

binarySearch


9 冒泡排序

最出名的排序算法之一,共有八大排序。

冒牌排序的代码相对较简单,两层循环,外循环冒泡轮数,内循环依次比较,时间复杂度为$ O(n^{2}) $。

public static void bubbleSort(int[] array){
    for(int i = 0; i < array.length - 1; i ++) {
        boolean flag = true; // 假设排序已完成
        for(int j = 0; j < array.length - i - 1; j ++) {
            if(array[j] > array[j + 1]) {
                int temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
                flag = false; // 发生对换,证明排序未完成
            }
        }
        if (flag) {
            break; // 结束排序,优化算法
        }
    }
}

10 稀疏数组

需求:编写五子棋游戏中,有存盘退出和续上盘的功能。

示例

问题:因为该二维数组中很多值是默认值0,因此记录了很多无意义的数据。

解决:稀疏数组。

当一个数组中大部分元素为0或同一值时,较浪费内存,可以使用稀疏数组来保存该数组。

稀疏数组的处理方式是:

  • 记录数组一共有几行几列,多少个不同值
  • 具有不同值的元素和行列记录在一个小规模数组中,从而缩小数组规模

原始数组:

$$ \begin{pmatrix} 0&0&0&22&0&0&15 \\ 0&11&0&0&0&17&0 \\ 0&0&0&-6&0&0&0 \\ 0&0&0&0&0&39&0 \\ 91&0&0&0&0&0&0 \\ 0&0&28&0&0&0&0 \end{pmatrix} $$

稀疏数组:

indexrowcolumnvalue
0678
10322
20615
31111
41517
523-6
63539
74091
85228

代码实现原始数组与稀疏数组互相转换:

// 将原始数组转换为稀疏数组
public static int[][] convertToSparse(int[][] original) {
    // 1.获取有效值个数
    int sum = 0;
    for(int[] row : original) { // 行
        for (int column : row) { // 列
            if (column != 0) { // 判断是否为有效值
                sum++;
            }
        }
    }

    // 2.创建稀疏数组
    int[][] sparse = new int[sum + 1][3];
    sparse[0][0] = original.length;
    sparse[0][1] = original[0].length;
    sparse[0][2] = sum;

    // 3.存储数据
    int count = 1;
    for(int i = 0; i < original.length; i ++) {
        for(int j = 0; j < original[i].length; j ++) {
            if(original[i][j] != 0) {
                sparse[count][0] = i;
                sparse[count][1] = j;
                sparse[count][2] = original[i][j];
                count ++;
            }
        }
    }

    return sparse;
}
// 将稀疏数组转换为原始数组
public static int[][] convertToOriginal(int[][] sparse) {
    // 1.创建原始数组
    int[][] original = new int[sparse[0][0]][sparse[0][1]];

    // 2.存储数据
    for(int i = 1; i <= sparse[0][2]; i ++) {
        original[sparse[i][0]][sparse[i][1]] = sparse[i][2];
    }

    return original;
}

测试之,

测试

感谢 狂神说 提供的java学习资源。


暂无评论

发表评论