Java 数组

136 阅读2分钟

数组

数组就是一组数据, 可以存放多个相同数据类型数据, 是属于引用类型

数组的创建与使用

  1. 动态初始化

数据类型 数组名[] = new 数据类型[大小]

double[] abc 与 double abc[] 等价

使用下标来进行赋值

  1. 先声明数组 然后创建数组
double scores[]; // 先声明这是一个数组 (还没分配内存空间)
scores = new double[10]; // 分配内存空间 下面就可以存放数据了
  1. 静态初始化

如: int a[] = {1,2,3,4,5}; // 用于知道有多少个数据存储的场景

注意事项

数组属于引用类型, 数组型数据为对象

数组赋值机制

基本数据类型是值传递 (复制另一份数值 地址不一样) 形参的任何改变不会影响实参~

数组在默认情况是引用传递, 赋的是地址 (地址一样) (拷贝的是地址, 赋值后 引用到同一个地址)

(如在函数参数传递时为引用传递, 那若函数的的引用类型 = null 与不会影响主函数 引用类型数据的内容)

在栈开辟一个空间 指向一块内存 (存的是地址) 然后该内存地址里的内容是在堆中存放

数组反转

public static void main(String[] args) {
    int[] arr = {11,22,33,44,55,66};
    for (int i = 0; i<arr.length/2;i++){ // arr[5] <-> arr[0] arr[4] <-> arr[1] arr[3] <-> arr[2]
        int temp = arr[i];
        arr[i] = arr[arr.length-i-1];
        arr[arr.length-i-1] = temp;
    }
    // 当然可以让 arr 逆序赋值给 arr2
    for (int i = 0; i < arr.length; i++) {
        System.out.println(arr[i]);
    }
}

数组扩容

重新定义一个数组 然后赋值给那个数组, 然后让旧数组指向新定义的扩容数组即可

public static void main(String[] args) {
 // 数组扩容
    int[] arr = {1,2,3};
    int[] newArr = new int[arr.length+1];
    for (int i = 0; i<arr.length; i++){
        newArr[i] = arr[i];
    }
    newArr[newArr.length-1] = 5; // 扩容的那个数
    arr = newArr; // 让旧数组指向新数组~
    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i]+" "); // 1 2 3 5 扩容成功~
    }
}
public static void main(String[] args) {
 // 数组动态扩容
    Scanner myScanner = new Scanner(System.in);
    int[] arr = {1,2,3};
    while(true){
        int[] newArr = new int[arr.length+1];
        for (int i = 0; i<arr.length; i++){
            newArr[i] = arr[i];
        }
        System.out.println("请输入想要添加的元素");
        int add = myScanner.nextInt();
        newArr[newArr.length-1] = add; // 扩容的那个数
        arr = newArr; // 让旧数组指向新数组~
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" "); // 1 2 3 5 扩容成功~
        }
        System.out.println();
        // 是否继续添加
        System.out.println("是否需要继续添加数据y/n");
        char keyboard = myScanner.next().charAt(0);
        if(keyboard == 'n'){
            break;
        }else if(keyboard == 'y'){
            continue;
        } // 可以增加逻辑增加防止乱输入
    }
    System.out.println("你已退出添加数组元素程序");
}

数组的缩减 思路类似

数组排序

冒泡排序

public static void main(String[] args) {
    // 冒泡排序
    int[] arr = { 2, 3, 1, 5, 78, 32, -1, -999 };
    boolean flag = true;
    for (int i = 0; i < arr.length - 1; i++) { // 外层循环 (几轮比较)
        for (int j = 0; j < arr.length - i - 1; j++) { // 每次遍历比较的次数 (每轮)
            if (arr[j] > arr[j + 1]) { // 若前面的数据大于后面的数据 就交换
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
                flag = false;
            }
        }
        if (flag) {
            break;
        }
    }
    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i]+" ");
    }
}

二维数组

二维数组本质是由多个一维数组组成的, 其各个一维数组长度可以一致, 也可以不相同

 public static void main(String[] args) {
        // 二维数组 第一个[]表示这个二维数组有多少个元素 第二个是每个元素里有多少个元素
        // 二维数组中的一维数组元素个数不一定全部一样
        int[][] arr1 = { { 1, 2, 3, 4 }, { 2, 3, 4, 5,6,7,8,9}, { 3, 4, 5, 6 }, { 4, 5, 6, 7 } };
        for (int i = 0; i < arr1.length; i++) {
            for (int j = 0; j < arr1[i].length; j++) {
                System.out.print(arr1[i][j]);
            }
            System.out.println();
        }
    }

初始化形式与一维数组的类似

内存分析

二维数组的简单应用(动态二维数组)

 public static void main(String[] args) {
    /* 动态创建二维数组, 并打印
        i = 0: 1
        i = 1: 2  2
        i = 2: 3  3  3
    */
    int[][] arr = new int[3][]; // 创建二维数组, 只是创建了一维数组的个数
    for (int i = 0; i < arr.length; i++) {
        // 给二维数组的每一个元素(即一维数组)开辟内容空间
        arr[i] = new int[i + 1]; // 若不给一维数组开辟空间, 那么 arr[i] 就是 null
        // 遍历一维数组, 并给一维数组赋值~
        for (int j = 0; j < arr[i].length; j++) {
            arr[i][j] = i + 1;
        }
    }
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < arr[i].length; j++) {
            System.out.print(arr[i][j] + " ");
        }
        System.out.println();
    }
}

杨辉三角(二维数组的经典应用!)

第一种方法是一开始就创建了10*10的二维数组 比较费空间 (因为有些空间浪费了, 没用来存数据)

第二种方法是先是定下有多少个一维数组(即二维数组的行数), 然后再动态给一维数组开辟空间 然后赋值~

public static void main(String[] args) {
    // 打印杨辉三角~
    int[][] arr = new int[10][10];
    arr[0][0] = 1;
    arr[1][0] = 1;
    arr[1][1] = 1; //  因为比较特殊 我就先初始化了, 当然初始化的工作也能放到循环里面进行
    for (int i = 2; i < arr.length; i++) {
        for (int j = 0; j <= i; j++) {
            if (j == 0 || i == j) {
                arr[i][j] = 1;
            } else { // 除了一头一尾 那就是通过公式计算值了
                arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];   
            }
        }
    }
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j <= i; j++) {
            System.out.print(arr[i][j]+" ");
        }
        System.out.println();
    }
}
 public static void main(String[] args) {
    // 打印杨辉三角~
    int[][] arr = new int[10][];
    for (int i = 0; i < arr.length; i++) {
        arr[i] = new int[i + 1]; // 给每一个一维数组(二维数组的行)开辟空间
        for (int j = 0; j < arr[i].length; j++) {
            // 每行数据的一头一尾都是1!
            if(j == 0 || j == arr[i].length-1){
                arr[i][j] = 1;
            }else{ // 其余的就可以 按照公式计算~
                arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];
            }
        }

    }
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j <= i; j++) {
            System.out.print(arr[i][j]+" ");
        }
        System.out.println();
    }
}

练习题

已知有一个升序序列, 当添加一个数据后, 序列仍有序, 该如何实现?

public static void main(String[] args) {
    // 已知有一个升序序列, 当添加一个数据后, 序列仍有序
    int[] arr = { 10, 12, 45, 90 };
    int index = -1; // 寻找待插入的位置
    while (true) {
        Scanner myscanner = new Scanner(System.in);
        System.out.println("请输入待插入的数据");
        int insertData = myscanner.nextInt();
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] >= insertData) {
                index = i;
                break;
            }
        }
        if (index == -1)
            index = arr.length; // 遍历完发现index数值没有变化 说明数组的元素都比待插入元素小
        int[] newArr = new int[arr.length + 1]; // 扩容后的数组 用于存放新的数组~
        for (int j = 0; j < index; j++) {
            newArr[j] = arr[j];
        }
        for (int j = index + 1; j < newArr.length; j++) {
            newArr[j] = arr[j - 1];
        }
        newArr[index] = insertData;

        // 拷贝数组的另外一种做法 (与上面方法类似)
        for (int i = 0, j = 0; i < newArr.length; i++) {
            if (i != index) {
                newArr[i] = arr[j];
                j++;
            } else {
                newArr[i] = insertData;
            }
        }
        
        arr = newArr; // 让arr指向新的数组 -> 完成扩容~
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
        System.out.println("请问还需要输入数据么?(y/n)");
        char character = myscanner.next().charAt(0);
        if (character == 'y') {
            continue;
        } else {
            break;
        }
    }