Java基础学习(三)-数组

114 阅读19分钟

数组

Java基础学习---点击进入学习

1.数组的概念

概念:一组连续的存储空间,存储多个相同数据类型的值,长度是固定

2.数组的定义方式

先声明、再分配空间: 数据类型[] 数组名; 数组名 = new 数据类型[长度];

声明并分配空间: 数据类型[] 数组名 = new 数据类型[长度];

声明并赋值(繁): 数据类型[] 数组名 = new 数据类型[]{value1,value2,value3,...};

声明并赋值(简): 数据类型[] 数组名 = {value1,value2,value3,...};


/**
 * @author WHD
 * @description TODO
 * @date 2024/1/3 14:10
 *  数组的4种声明方式
 */
public class TestArrayDefine {
    public static void main(String[] args) {
        // 方式1 先声明 再开辟空间
        int [] arr1;
        arr1 = new int[3];


        // 方式2 声明并且分配空间
        int [] arr2  = new int[5];


        // 方式3 声明并且赋值 繁琐 (注意,这种方式中括号中不能写数组长度)
        int [] arr3 = new int[]{55,663,789,456,11,22};

        // 方式4 声明并且赋值 简单
        int [] arr4 = {11,22,55,77,88};

    }
}

3.数组的使用

数组的使用

元素:数组中的每一个数据,称之为元素 element

下标:也叫角标,索引,英文名称index,是自动生成的,从0开始,后续依次加1,用于访问数组中的元素

元素的访问:对数组中的数据赋值以及取值的操作,称之为元素的访问

访问格式:

​ 赋值 数组名[下标] = 值;

​ 取值 System.out.println(数组名[下标]);

不能访问不存在的下标,否则会出现数组下标越界异常:ArrayIndexOutOfBoundsException


/**
 * @author WHD
 * @description TODO
 * @date 2024/1/3 14:19
 *  数组的使用
 *
 *      元素:数组中的每一个数据,称之为元素  element
 *      下标:也叫角标,索引,英文名称index,是自动生成的,从0开始,后续依次加1,用于访问数组中的元素
 *      元素的访问:对数组中的数据赋值以及取值的操作,称之为元素的访问
 *      访问格式:
 *          赋值 数组名[下标] = 值;
 *          取值 System.out.println(数组名[下标]);
 *
 *
 *  不能访问不存在的下标,否则会出现数组下标越界异常:ArrayIndexOutOfBoundsException
 */
public class TestArrayUse {
    public static void main(String[] args) {
        int [] arr1 = new int[5];
        // 赋值
        arr1[0] = 11;
        arr1[1] = 88;
        arr1[2] = 78;
        arr1[3] = 66;
        arr1[4] = 77;
//        arr1[15] = 678;

        // 取值
        System.out.println("第1个元素的值为:" + arr1[0]);
        System.out.println("第2个元素的值为:" + arr1[1]);
        System.out.println("第3个元素的值为:" + arr1[2]);
        System.out.println("第4个元素的值为:" + arr1[3]);
        System.out.println("第5个元素的值为:" + arr1[4]);
//        System.out.println("第6个元素的值为:" + arr1[5]);

    }
}

4. 数组的遍历

数组的遍历

遍历:逐一对数组中的元素进行访问 这个操作称之为数组遍历


import java.util.Scanner;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/3 14:29
 *  数组的遍历
 *  遍历:逐一对数组中的元素进行访问 这个操作称之为数组遍历
 */
public class TestArrayForeach {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int [] nums = new int[5];

        // 通过循环的方式给数组中的元素赋值
        for(int i = 0;i < 5;i++){
            System.out.println("请输入数组中的第" + (i + 1) + "个元素的值");
            nums[i] = input.nextInt();
        }


        // 通过循环的方式将数组中的元素都取出来
        for(int i = 0;i < 5;i++){
            System.out.println("第" + (i + 1) + "个元素的值为:" + nums[i]);
        }






    }
}

5.数组的属性

数组的属性:length 表示数组的长度 是一个int类型的整数

使用方式:数组名.length

使用length属性好处:阅读性更强 不会出现下标错误的问题

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/3 14:35
 *  数组的属性:length 表示数组的长度 是一个int类型的整数
 *  使用方式:数组名.length
 *  使用length属性好处:阅读性更强 不会出现下标错误的问题
 */
public class TestArrayField {
    public static void main(String[] args) {
        int [] nums = new int[]{56,1,2,4,7,8};
        System.out.println(nums.length);
        for(int i = 0;i < nums.length;i++){
            System.out.println(nums[i]);
        }
    }
}

6.数组的默认值

数组的默认值:数组中的元素是有默认值的 开辟完空间以后 默认值即存在


/**
 * @author WHD
 * @description TODO
 * @date 2024/1/3 15:08
 *  数组的默认值:数组中的元素是有默认值的  开辟完空间以后 默认值即存在
 */
public class TestArrayDefaultValue {
    public static void main(String[] args) {
        byte [] arr1 = new byte[3];
        for(int i = 0;i < arr1.length;i++){
            System.out.print(arr1[i] + "\t");
        }
        System.out.println();
        System.out.println(arr1);

        System.out.println("--------------------------------------");

        short [] arr2 = new short[4];
        System.out.println(arr2);
        for(int i = 0;i < arr2.length;i++){
            System.out.print(arr2[i] + "\t");
        }
        System.out.println();

        System.out.println("--------------------------------------");
        int [] arr3 = new int[5];
        System.out.println(arr3);
        for(int i = 0;i < arr3.length;i++){
            System.out.print(arr3[i] + "\t");
        }
        System.out.println();
        System.out.println("--------------------------------------");
        long [] arr4 = new long[6];
        System.out.println(arr4);
        for(int i = 0;i < arr4.length;i++){
            System.out.print(arr4[i] + "\t");
        }
        System.out.println();
        System.out.println("--------------------------------------");

        float [] arr5 = new float[2];
        for (int i = 0; i < arr5.length; i++) {
            System.out.print(arr5[i] + "\t");
        }
        System.out.println();

        System.out.println("--------------------------------------");
        double [] arr6 = new double[3];
        for (int i = 0; i < arr6.length; i++) {
            System.out.print(arr6[i] + "\t");
        }
        System.out.println();
        System.out.println("--------------------------------------");

        char [] arr7 = new char[4];
        for (int i = 0; i < arr7.length; i++) {
            System.out.print(arr7[i] + "\t");
        }
        System.out.println();
        System.out.println("--------------------------------------");

        boolean [] arr8 = new boolean[5];
        for (int i = 0; i < arr8.length; i++) {
            System.out.print(arr8[i] + "\t");
        }
        System.out.println();
        System.out.println("--------------------------------------");

        String [] arr9 = new String[3];
        for (int i = 0; i < arr9.length; i++) {
            System.out.print(arr9[i] + "\t");
        }
        System.out.println();




    }
}

7. 数组的扩容

数组的扩容.png

数组的扩容

1.创建大于原数组长度的新数组。

2.将原数组中的元素依次复制到新数组中。

3.将新数组的地址赋值给原数组。

数组作为引用数据类型 其数组名中保存的是指向堆中的地址 将一个数组 直接 赋值给另外一个数组 赋值是地址


/**
 * @author WHD
 * @description TODO
 * @date 2024/1/3 15:19
 *  数组的扩容
 *      1.创建大于原数组长度的新数组。
 *      2.将原数组中的元素依次复制到新数组中。
 *      3.将新数组的地址赋值给原数组。
 */
public class TestArrayGrow {
    public static void main(String[] args) {
        int [] oldArr = {1,2,3,4,5};

        int [] newArr = new int[oldArr.length * 2];

        for(int i = 0;i < oldArr.length;i++){
            newArr[i] = oldArr[i];
        }

        System.out.println("---------------------------------------------");

        for(int i = 0;i < newArr.length;i++){
            System.out.println(newArr[i]);
        }


        System.out.println("oldArr内存地址:" + oldArr);
        System.out.println("newArr内存地址:" + newArr);

        // 数组作为引用数据类型 其数组名中保存的是指向堆中的地址
        // 将一个数组 直接 赋值给另外一个数组 赋值是地址
        oldArr = newArr;

        System.out.println("地址赋值以后");

        System.out.println("oldArr内存地址:" + oldArr);
        System.out.println("newArr内存地址:" + newArr);

        System.out.println("oldArr数组长度:" + oldArr.length);
        System.out.println("newArr数组长度:" + newArr.length);


    }
}

8.复制数组的方式

数组的复制

1.自己编写循环实现元素复制

2.使用System.arraycopy(原数组,原数组起始,新数组,新数组起始,长度);

3.使用java.util.Arrays.copyOf(原数组, 新长度);//返回带有原值的新数组。


import java.util.Arrays;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/3 15:41
 *  数组的复制
 *      1.自己编写循环实现元素复制
 *      2.使用System.arraycopy(原数组,原数组起始,新数组,新数组起始,长度);
 *      3.使用java.util.Arrays.copyOf(原数组, 新长度);//返回带有原值的新数组。
 */
public class TestArrayCopy {
    public static void main(String[] args) {
        int [] nums1 = {1,2,3,4,5};

        int [] nums2 = new int[10];

        System.arraycopy(nums1, 1, nums2, 5,4);

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

        System.out.println("-----------------------------------------");

        int [] nums = {11,22,33,44,55};

        int [] arr = Arrays.copyOf(nums, 10);

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




    }
}

9. 课堂练习

数组的练习:统计int类型数组中所有元素的总和 以及 平均值


/**
 * @author WHD
 * @description TODO
 * @date 2024/1/3 15:50
 *  数组的练习:统计int类型数组中所有元素的总和 以及 平均值
 */
public class TestArrayExercise1 {
    public static void main(String[] args) {
        int [] arr1 = {11,22,33,44,55,66};

        // 定义变量 用于统计总和
        int sum = 0;

        // 遍历数组 
        for (int i = 0; i < arr1.length; i++) {
            sum += arr1[i]; // 将数组中的每个元素 进行累计
        }

        System.out.println("数组总和为:" + sum); // 打印总和
        System.out.println("数组平均值为:" + sum / arr1.length); // 打印平均值


    }
}

求一个数组中的最大值,或者最小值。

分析:先假设一个最大值,将其依次与其他元素比较,遇到更到的元素,则交换头衔,直到比较完毕。

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/3 15:52
 *  求一个数组中的最大值,或者最小值。
 *
 *  分析:先假设一个`最大值`,将其依次与其他元素比较,遇到更到的元素,则交换`头衔`,直到比较完毕。
 */
public class TestArrayExercise2 {
    public static void main(String[] args) {
        int [] nums = {89,562,741,11,666,999,521,321,20};

        // 假设第一个为最大元素
        int max = nums[0];
        // 假设第一个为最小元素
        int min = nums[0];

        // 遍历数组
        for(int i = 1;i < nums.length;i++){
            // 判断元素大小 如果遇到更大的
            if(max < nums[i]){
                max = nums[i]; // 则交换最大元素的头衔
            }
            // 如果遇到更小的
            if(min > nums[i]){
                min = nums[i]; // 则交换最小元素的头衔
            }
        }


        // 打印最大 最小值
        System.out.println("最大的元素为:" + max);
        System.out.println("最小的元素为:" + min);


    }
}

10.数组类型的参数和返回值

数组作为参数,作为返回值使用,使用方式和之前一致。

数组类型的参数和返回值

需求:

​ 1.编写方法实现统计一个学生的5门成绩 并且返回

​ 2.编写方法实现接收用户输入的5门成绩 实现遍历打印


import java.util.Scanner;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/5 9:16
 *  数组类型的参数和返回值
 *
 *  需求:
 *      1.编写方法实现统计一个学生的5门成绩  并且返回
 *      2.编写方法实现接收用户输入的5门成绩 实现遍历打印
 */
public class TestArrayParamAndReturnValue {

    /**
     *  接收用户输入的5门成绩  需要返回值 但是不需要参数
     * @return
     */
    public static double[] inputScores(){
        // 定义数组用于接下类保存成绩
        double [] scores = new double[5];

        Scanner input = new Scanner(System.in);

        for(int i = 0;i < scores.length;i++){
            System.out.println("请输入第" + (i + 1) + "门成绩");

            scores[i] = input.nextDouble();
        }
        return scores;
    }
    /**
     *  打印成绩的方法 需要参数 但是不需要返回值
     * @param scores
     */
    public static void printScores(double [] scores){
        for(int i = 0;i < scores.length;i++){
            System.out.println("第" + (i + 1) + "门成绩为:" + scores[i]);
        }
    }

    public static void main(String[] args) {
        double [] scores = inputScores();
        printScores(scores);
    }


}

11.值传递和引用传递的区别?

面试题:值传递和引用传递的区别?

基本数据类型传参属于值传递 传递的是一个值的副本 值的拷贝 在方法中对值的改变 不会影响原变量

引用数据类型传参属于引用传递 传递的是一个地址值 在方法根据地址值所做的操作 将影响所有指向此地址的变量

String类型是特殊的引用数据类型 作为参数传递不会影响原变量

Java官方明确说明了,Java中只有值传递,没有引用传递,所谓的引用传递其实也属于值传递

只不过这个值是一个:地址值


/**
 * @author WHD
 * @description TODO
 * @date 2024/1/5 9:34
 *  面试题:值传递和引用传递的区别?
 *     基本数据类型传参属于值传递 传递的是一个值的副本 值的拷贝 在方法中对值的改变 不会影响原变量
 *     引用数据类型传参属于引用传递 传递的是一个地址值 在方法根据地址值所做的操作 将影响所有指向此地址的变量
 *     String类型是特殊的引用数据类型 作为参数传递不会影响原变量
 *
 *
 *     Java官方明确说明了,Java中只有值传递,没有引用传递,所谓的引用传递其实也属于值传递
 *     只不过这个值是一个:地址值
 */
public class TestInterview {
    public static void m1(int num){
        num++;
        System.out.println("num = " + num);
    }
    public static void m2(int [] nums){
        for (int i = 0; i < nums.length; i++) {
            nums[i]++;
        }

    }
    public static void main(String[] args) {
        int a = 10;
        m1(a);
        System.out.println("a = " + a);

        System.out.println("----------------------------------");

        int [] b = {1,2,3,4,5};
        m2(b);
        for (int i = 0; i < b.length; i++) {
            System.out.print(b[i] + "\t");
        }
        System.out.println();
    }
}

12.可变长参数

可变长参数:可以接收0个或者多个相同类型的实参 最终实现还是数组 所以和数组的使用方式一致

要求:

1.形参列表中只能有一个可变长参数

2.必须书写在形参列表的末尾

说明:现阶段使用不到 后续讲解到反射 将大量的使用到可变长参数


/**
 * @author WHD
 * @description TODO
 * @date 2024/1/5 10:17
 *  可变长参数:可以接收0个或者多个相同类型的实参 最终实现还是数组 所以和数组的使用方式一致
 *  要求:
 *      1.形参列表中只能有一个可变长参数
 *      2.必须书写在形参列表的末尾
 *
 *  说明:现阶段使用不到 后续讲解到反射 将大量的使用到可变长参数
 */
public class TestChangeableParam {
    public static void m1(int a,int ... args){
        System.out.println("m1方法开始执行");
        for (int i = 0; i < args.length; i++) {
            System.out.println(args[i]);
        }
        System.out.println("m1方法执行完毕");
    }

    public static void main(String[] args) {
        m1(1,2,3,4,5,6,7,8,11,2,3);



    }


}

13.排序算法

13.1 冒泡排序

冒泡排序.png

冒泡排序1.gif

冒泡排序:两个相邻的元素比较大小,如果条件成立,则交换位置。

外层循环控制比较的轮数:长度 - 1 (n - 1)

内层循环控制每一轮比较的次数:最多的一次为 长度-1 后续每一轮都递减1 n - 1 - ?(递增的值)

外层循环:n - 1

内层循环:n - 1 - i

for(n - 1){

​ for(n - 1 -i){

​ if(条件成立){

​ 交换位置;

​ }

​ }

}



/**
 * @author WHD
 * @description TODO
 * @date 2024/1/5 10:28
 *  冒泡排序:两个相邻的元素比较大小,如果条件成立,则交换位置。
 *
 *  外层循环控制比较的轮数:长度 -  1  (n - 1)
 *  内层循环控制每一轮比较的次数:最多的一次为 长度-1 后续每一轮都递减1  n - 1 - ?(递增的值)
 *
 *
 *  外层循环:n - 1
 *  内层循环:n - 1 - i
 *
 *  for(n - 1){
 *      for(n - 1  -i){
 *          if(条件成立){
 *              交换位置;
 *          }
 *      }
 *  }
 *
 *
 */
public class BubbleSort {
    public static void main(String[] args) {
        int [] nums = {89,44,55,74,12,63,220,12,3};
        for(int i = 0;i < nums.length - 1;i++){ // 控制的轮数 为 n - 1  相当于行
            for(int j = 0;j < nums.length - 1 - i;j++){ // 控制的每轮比较的次数  相当于列
                if(nums[j] < nums[j + 1]){
                    int temp = nums[j];
                    nums[j] = nums[j + 1];
                    nums[j + 1] = temp;
                 }
            }

            System.out.println("第" + (i + 1) + "轮比较完成以后,顺序为:" + Arrays.toString(nums));


        }

        System.out.println("-------------------排序完成----------------------");

        for (int i = 0; i < nums.length; i++) {
            System.out.print(nums[i] + "\t");
        }

    }
}

13.2 冒泡排序优化

因为冒泡排序都是两个相邻的元素比较,且每一轮只能确定一个元素的位置,所以正常情况下,必须要比较完成长度-1轮,但有些情况不需要比较长度-1轮,即已经排列正确,我们可以进行优化,以减少不必要的比较的轮数。

思路:在外层循环中加入布尔类型的变量,初始值为true,当内层条件成立,则表示需要交换位置,改变布尔变量的值,在一轮比较完成以后,对布尔变量的值判断,如果还未true,则表示没有交换一次位置,也就表示顺序已经正确,则可以提前结束循环。


import java.util.Arrays;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/5 11:36
 *  冒泡排序完善
 */
public class BubbleSortPerfection {
    public static void main(String[] args) {
        int [] nums = {89,44,55,74,12,63,220,12,3};
        for(int i = 0;i < nums.length - 1;i++){ // 控制的轮数 为 n - 1  相当于行

            boolean flag = true; // 定义布尔类型变量 标记

            for(int j = 0;j < nums.length - 1 - i;j++){ // 控制的每轮比较的次数  相当于列
                if(nums[j] < nums[j + 1]){
                    flag = false; // 如果条件成立 则表示需要交换位置 即表示顺序还未排列正确
                    int temp = nums[j];
                    nums[j] = nums[j + 1];
                    nums[j + 1] = temp;
                }
            }
            System.out.println("第" + (i + 1) + "轮比较完成以后,顺序为:" + Arrays.toString(nums));

            if(flag){
                break;
            }
        }
        System.out.println("-------------------排序完成----------------------");

        for (int i = 0; i < nums.length; i++) {
            System.out.print(nums[i] + "\t");
        }
    }
}

13.3 选择排序

选择排序.png

选择排序2.gif

import java.util.Arrays;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/5 13:53
 *
 *  回顾冒泡排序是如何实现的?
 *  冒泡排序是两个相邻的元素比较大小,如果需要交换位置,则会立即交换,这样就会出现某些元素移动很多次的现象
 *
 *  选择排序:固定位置的元素,依次与其他位置的元素比较大小,遇到需要交换位置的元素,
 *  不会立即交换位置,而是交换比较的元素,等待一轮比较完成以后,再交换一次位置。
 *
 *  分析:选择排序可以理解为两个元素的比较 分别为元素A  和 元素B
 *  元素A : 从第一个 元素开始 到倒数第二个元素 都将充当一遍元素A  0 n - 1
 *  元素B : 从元素A后边相邻的位置开始 直到最后一个元素   i + 1   n
 *  外层循环属于比较的元素A
 *  内层循环属于比较的元素B
 *
 */
public class SelectionSort {
    public static void main(String[] args) {
        int [] nums = {-99,89,44,55,74,12,63,220,3};

        int count = 0;

        for(int i = 0;i < nums.length - 1;i++){ // 元素A

            int index = i; // 定义变量index 每轮比较开始 都设定为和i相同 用于作为交换下标

            for(int j = i + 1;j < nums.length;j++){ // 元素B
                if(nums[index] > nums[j]){
                    index = j; // 将更小的 或者 更大的 元素的下标 赋值给index 下一次比较将使用新的元素 继续往后比
                }
            }
            if(index != i){
                count++;
                int temp = nums[index];
                nums[index] = nums[i];
                nums[i] = temp;
            }
            System.out.println("第" + (i + 1) + "次比较完成以后顺序为:" + Arrays.toString(nums));
        }
        System.out.println(Arrays.toString(nums));
        System.out.println("一共交换了" + count + "次位置");

    }





}

13.4 算法复杂度

算法复杂度.png

13.5JDK提供的排序

JDK提供的排序:Arrays.sort() 升序排序 底层实现为快速排序

import java.util.Arrays;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/5 14:41
 *  JDK提供的排序:Arrays.sort() 升序排序  底层实现为快速排序
 */
public class TestArraysSort {
    public static void main(String[] args) {
        int [] nums = {-99,89,44,55};

        Arrays.sort(nums);

        System.out.println(Arrays.toString(nums));

        int [] newNum = new int[nums.length];

        // 定义i从0开始 j从长度-1开始
        // 循环条件为 循环次数
        // i递增  j递减
        for(int i = 0,j = nums.length -1; i < nums.length; i++,j--){
            newNum[i] = nums[j]; // 将原数组最后的元素 赋值给新数组第一个位置的元素
        }

        System.out.println(Arrays.toString(newNum));






    }
}

14.二维数组(了解)

二维数组:数组中的元素还是一维数组


/**
 * @author WHD
 * @description TODO
 * @date 2024/1/5 15:21
 *  二维数组:数组中的元素还是一维数组
 */
public class Test2DArray {
    public static void main(String[] args) {
        int [] arr1 = {1,2,3,4,5};

        int [][] arr2 = {{11,22} , {1,2,3,4,5} ,{666,999,888}};
        System.out.println(arr2[0]);
        System.out.println(arr2[0][0]);
        System.out.println(arr2[0][1]);

        System.out.println(arr2[1]);
        System.out.println(arr2[1][0]);
        System.out.println(arr2[1][1]);
        System.out.println(arr2[1][2]);
        System.out.println(arr2[1][3]);
        System.out.println(arr2[1][4]);

        System.out.println(arr2[2]);
        System.out.println(arr2[2][0]);
        System.out.println(arr2[2][1]);
        System.out.println(arr2[2][2]);

        System.out.println("-----------------------------------");

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




    }
}

二维数组的定义

NullPointerException:空指针异常,只要使用一个指向为null的引用数据类型,继续访问任何的属性,方法,

或者使用一个指向为null的数组,存值,取值,就会出现空指针异常。


/**
 * @author WHD
 * @description TODO
 * @date 2024/1/5 15:27
 *  二维数组的定义
 *
 *  NullPointerException:空指针异常,只要使用一个指向为null的引用数据类型,继续访问任何的属性,方法,
 *  或者使用一个指向为null的数组,存值,取值,就会出现空指针异常。
 */
public class Test2DArrayDefine {
    public static void main(String[] args) {
        int [] nums = new int[3]; // 0 0 0


        // 方式1 : 先声明 再分配空间  高维度的长度必须指定 低维度的长度可以临时指定
        int [][] arr1;
        arr1 = new int[3][];

        System.out.println(arr1[0]);
        System.out.println(arr1[1]);
        System.out.println(arr1[2]);


        // NullPointerException
        arr1[0] = new int[5];
        arr1[0][0] = 11;
        arr1[0][1] = 12;
        arr1[0][2] = 13;
        arr1[0][3] = 14;
        arr1[0][4] = 15;

        arr1[1] = new int[4];
        arr1[1][0] = 33;
        arr1[1][1] = 33;
        arr1[1][2] = 33;
        arr1[1][3] = 33;

        arr1[2] = new int[3];
        arr1[2][0] = 666;
        arr1[2][1] = 666;
        arr1[2][2] = 666;

        // 方式2 连声明 带开辟空间  高维度的长度必须指定 低维度的长度也可以立即指定
        int [][] arr2 = new int[3][2];

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

        // 方式3  声明并且赋值 繁琐
        int [][] arr3 = new int[][]{ {1}, {22,22,33} , {33,555,666} };

        // 方式4  声明并且赋值 简单
        int [][] arr4 = { {1}, {22,22,33} , {33,555,666} };

    }
}

15.Arrays类

Arrays类是JDK提供的数组工具类 位于java.util包中 使用此类必须导包

binarySearch() 使用二分法查找指定元素在数组中的位置 使用二分法的前提为 数组必须是有序的

toString() 返回指定数组的字符串形式

sort() 升序排序

copyOf() 复制数组

fill() 填充数组


import java.util.Arrays;

/**
 * @author WHD
 * @description TODO
 * @date 2024/1/5 15:49
 *  Arrays类是JDK提供的数组工具类  位于java.util包中 使用此类必须导包
 *
 *  binarySearch() 使用二分法查找指定元素在数组中的位置 使用二分法的前提为 数组必须是有序的
 *  toString() 返回指定数组的字符串形式
 *  sort() 升序排序
 *  copyOf() 复制数组
 *  fill() 填充数组
 */
public class TestArrays {
    public static void main(String[] args) {
        int [] nums = {9,5,3,1,8,6,4,2};

        Arrays.sort(nums);

        System.out.println(Arrays.toString(nums));
        // 查找元素5在数组中的下标
        System.out.println(Arrays.binarySearch(nums, 1));

        int[] newNums = Arrays.copyOf(nums, 10);

        System.out.println(Arrays.toString(newNums));

        // 填充元素 使用666填充newNums数组 即将所有的元素都改为666
        Arrays.fill(newNums, 666);

        System.out.println(Arrays.toString(newNums));



    }
}

16. 二分查找

binarySearch.gif

二分查找.gif

二分查找:将一个有序的序列,一分为二,如果查找的元素小于中间值,则从左边查找,如果大于中间值,则从右边查找

如果等于中间值,则直接返回对应的下标。重复以上过程


/**
 * @author WHD
 * @description TODO
 * @date 2024/1/5 16:00
 *  二分查找:将一个有序的序列,一分为二,如果查找的元素小于中间值,则从左边查找,如果大于中间值,则从右边查找
 *  如果等于中间值,则直接返回对应的下标。重复以上过程
 */
public class TestBinarySearch {
    public static void main(String[] args) {
        int [] nums = {1,2,3,4,5,6,7,8};

        System.out.println(binarySearch(nums, 4));
    }
    public static int binarySearch(int [] nums,int num){
        // 定义起始位置
        int begin = 0;

        // 定义结束位置
        int end = nums.length -1;

        // 定义中间位置
        int middle = (begin + end) / 2;

        // 定义index 作为最终的返回值 初始值为-1
        int index = -1;

        // begin通常情况下 小于end
        // 因为最终二分的结果 就算是剩下一个元素 那么这个元素 既是begin 又是end  所以是等于
        // 所以最终的条件为 <=
        // 绝对不可能 begin 大于end
        while(begin <= end){
            if(num > nums[middle]){
                begin = middle + 1;
            }else if(num < nums[middle]){
                end = middle - 1;
            }else {
                index = middle;
                break;
            }
            // 每次更新完 begin 或者 end之后 中间值 也必须重新计算 所以 再次 (begin + end) / 2
            middle = (begin + end) / 2;
        }
        return index;
    }
}