day07_数组进阶

时间:2024-02-29 20:51:24

今日内容

零、 复习昨日
一、作业
二、引用类型[重要]
三、数组排序[面试|笔试]
四、数组拷贝
五、数组扩容
六、Arrays

零、 复习昨日

数组创建后能否改变长度

  • 不能,长度固定
    数组创建后能否存储不同类型的数据
  • 不能
    指定长度创建数组的语法,以int数组为例
    int[] arr = new int[4];

指定元素创建数组的语法,以int数组为例
int[] arr = new int[]{值,值,…}
int[] arr = {值,值,…}

数组取值,赋值语法
arr[0] = 1;// 存值
int a = arr[0]; // 取值

遍历是什么意思,尝试手写代码

  • 将数组的一个一个全部取出
    for(int i = 1;i < arr.length;i++){
    sout(arr[i])
    }
    数组的长度属性
    length

一、作业

package com.qf.homework;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @date 2024/2/27
 * @desc
 */
public class Homework {
    public static void main(String[] args) {
        // printArr( );
        printIndex();
    }

    // 遍历数组,将结果拼接成[1,2,3,4]
    public static void printArr() {
        int[] arr = {1, 2, 3, 4, 5, 6, 7};
        String s = "[";
        for (int i = 0; i < arr.length; i++) {
            s = s + arr[i];
            if (i != arr.length - 1) {
                s = s + ",";
            } else {
                s = s + "]";
            }
        }

        System.out.println(s);
    }

    // 2 根据元素找下标,找到输出下标,找不到输出-1
    public static void printIndex() {
        int[] arr = {1, 1, 2, 2, 3, 3, 4};
        int n = 5;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == n) {
                System.out.println(n+"在数组中存在,下标是"+i );
                return; // 单独一个return也可以,只是不返回值
                // 作用是结束方法
            }
        }
        System.out.println(n+"不存在与数组中" );
    }

    // 3 根据元素找下标,找到返回下标,找不到返回-1
    public static int getIndex() {
        int[] arr = {1, 1, 2, 2, 3, 3, 4};
        int n = 5;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == n) {
               return i;
            }
        }
        return -1;
    }
}

二、数组的应用

2.1 数组可以当方法参数

数组可以当方法的参数的,因为数组本身是一种引用数据类型!!!

public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7,8,9,10};
        printArr(arr);
    }

    // 演示1: 数组当参数用
    public static void printArr(int[] arr) {// int[] arr = arr;
        String s = "[";
        for (int i = 0; i < arr.length; i++) {
            s = s + arr[i];
            if (i != arr.length - 1) {
                s = s + ",";
            } else {
                s = s + "]";
            }
        }

        System.out.println(s);
    }

2.2 数组当返回值类型

数组可以当方法的返回值类型的,因为数组本身是一种引用数据类型!!!

  public static void main(String[] args) {
        int[] arr2 = getArr( );
        for (int i = 0; i < arr2.length; i++) {
            System.out.println(arr2[i] );
        }
    }

    // 2 演示数组当方法的返回值类型
    public static int[] getArr() {
        return new int[]{1,2,3};
    }

三、引用数据类型[重在理解]

java的数据类型

  • 基本数据类型: 四类八种
  • 引用数据类型: 数组,类,接口

通过下面的学习,了解

  • java的内存
    • 了解堆栈
  • 方法执行进栈,执行完弹栈,new的对象进堆
  • 何为引用?引用什么? 引用和基本的区别?
    • 引用就是地址值,通过引用找到堆中的对象
    • 引用类型对象在堆中,基本类型变量在栈中
    • 引用类型方法传参时,传递是地址值
    • 基本类型方法传参时,传递是数值
  • 变量的作用范围?
    • 每个方法都是独立的
    • 方法内的变量和其他方法没关系

3.1 基本类型是值传递

基本数据类型在方法传递参数

  • 基本数据类型是数据本身(值本身)在传递
  • 且基本类型数据存在于方法的栈中
  • 方法执行完弹栈消失,方法内的变量也随之消失
  public static void main(String[] args) {
        int a = 1;
        System.out.println("1) a = " + a );// 1
        changeBaseValue(a);
        System.out.println("4) a = " + a );// 还是1
    }

    // 改变基本数据类型的值
    public static void changeBaseValue(int a) {
        System.out.println("2) a = " + a );//1
        a *= 10;
        System.out.println("3) a = " + a );//10
    }

// 调用方法执行

image-20240227105128738

// 方法执行完会弹栈消失

image-20240227105205105

3.2 引用类型

引用类型在方法传参数时

  • 传递是对象的地址值,即引用
  • 方法接收引用后,通过引用找到堆中对象,改变它
  • 方法执行完弹栈,堆中对象还在
   public static void main(String[] args) {
        int[] arr = new int[]{1,2,3,4};
        System.out.println(arr );
        // 第一次输出
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" " );//1 2 3 4 
        }
        System.out.println( );

        changeRefValue(arr);

        // 第四次输出
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" " );// 10 20 30 40
        }
        System.out.println( );
    }

    // 改变引用数据类型的值
    public static void changeRefValue(int[] a) {
        // 第二次输出
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" " );//1 2 3 4 
        }
        System.out.println( );

        // 改变数组的值
        for (int i = 0; i < a.length; i++) {
            a[i] = a[i] * 10;// 放大10倍
        }

        // 第三次输出
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" " );//10 20 30 40 
        }
        System.out.println( );
    }

// 方法进栈,传递是地址值,操作是堆中的数组

image-20240227112109055

// 方法执行完弹栈

image-20240227110715909

四、排序算法[面试|笔试]

排序算法

  • 冒泡排序,选择排序,插入排序
  • 快速排序,堆排序,希尔排序,归并排序
  • 桶排序,基数排序,计数排序

4.1 冒泡排序

思路: 相邻两两比较,交换位置

冒泡排序

package com.qf.array;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @date 2024/2/27
 * @desc 排序算法
 */
public class Demo3 {

    public static void main(String[] args) {
        maopao();
    }

    // 冒泡排序,实现从小到大
    public static void maopao(){
        int[] arr = {5,4,3,2,1};
        // 排序前调用方法打印数组
        printArr(arr);

        // 开始排序
        // 外面循环控制趟数.-1是因为最后一趟不用比较,结果已出
        for (int i = 0; i < arr.length - 1; i++) {
            // 里面控制比较次数
            // -1是为了防止下标越界,-i是因为每次都可以少几次,
            // 因为后面的数字的大小已经固定
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j+1]) {
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
        // 排序完调用方法打印数组
        printArr(arr);
    }

    // 自己设计的帮助遍历数组的方法
    public static void printArr(int[] arr) {
        String s = "[";
        for (int i = 0; i < arr.length; i++) {
            s = s + arr[i];
            if (i != arr.length - 1) {
                s = s + ",";
            } else {
                s = s + "]";
            }
        }
        System.out.println(s);
    }
}

image-20240227115147615

4.2 选择排序

思路: 找最小元素 记住下标,与前面第1个(2,3)交换位置。。。。

选择排序

 // 选择排序
    public static void xuanze() {
        int[] arr = {5,4,3,2,1,7,6};
        // 排序前调用方法打印数组
        printArr(arr);
        
        // 开始排序
        for (int i = 0; i < arr.length; i++) {
            int minIndex = i;
            for (int j = i; j < arr.length; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }
            int temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
        // 排序前调用方法打印数组
        printArr(arr);
    }

image-20240227151012505

五、数组拷贝[了解]

数组拷贝: 将一个数组中的元素拷贝到另外一个数组中.

5.1 自己手动实现

    // 数组拷贝方式1:自己实现
    public static void arrayCopyByMySelf() {
        // 将arr1数组的元素拷贝到arr2中
        int[] arr1 = {4,2,5,1,3};

        // 创建arr2数组
        int[] arr2 = new int[arr1.length];
        // 开始拷贝
        for (int i = 0; i < arr1.length; i++) {
            arr2[i] = arr1[i];
        }

        // 拷贝完,查看arr2的效果
        for (int i = 0; i < arr2.length; i++) {
            System.out.println(arr2[i] );
        }
    }

5.2 Arrays.copyOf

Arrays是jdk提供的类用来操作数组的,copyOf 用来拷贝数组的

    // 数组拷贝方式2:通过Arrays实现
    public static void arrayCopyByArrays() {
        // 将arr1数组的元素拷贝到arr2中
        int[] arr1 = {4, 2, 5, 1, 3};

        // 使用Arrays.copyOf方法
        // 参数1是要拷贝的数组
        // 参数2是要生成的数组的长度
        int[] arr2 = Arrays.copyOf(arr1, arr1.length-2);

        // 拷贝完,查看arr2的效果
        for (int i = 0; i < arr2.length; i++) {
            System.out.println(arr2[i]);
        }


    }

5.3 System.arraycopy

System是jdk提供的类,其中方法arraycopy完成数组拷贝

  // 数组拷贝方式3:通过System实现
    public static void arrayCopyBySystem() {
        // 将arr1数组的元素拷贝到arr2中
        int[] arr1 = {4, 2, 5, 1, 3};

        int[] arr2 = new int[arr1.length];
        /**
         * 参数1: 拷贝源数组
         * 参数2: 从源数组哪里开始拷贝(位置下标)
         * 参数3: 目的地数组
         * 参数4: 将数组放到目的地数组的哪个位置(下标)
         * 参数5: 拷贝多少个
         */
        System.arraycopy(arr1,1,arr2,1,3);
        // 拷贝完,查看arr2的效果
        for (int i = 0; i < arr2.length; i++) {
            System.out.println(arr2[i]);
        }
    }

六、数组扩容

数组本身确定是不能扩容的,此处这个"数组扩容"是指重新创建更大的数组,将之前数组元素拷贝到新数组中,接着去使用新的大数组去存储数据,感觉上是 数组扩容了… 其实创建是了更大的新数组

package com.qf.array;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @date 2024/2/27
 * @desc 数组扩容
 */
public class Demo5 {

    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        System.out.println("arr第一次的地址:"+arr );
        System.out.println("扩容前arr: " );
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] +" ");
        }
        System.out.println( );

        // 扩容
        arr = changeSize(arr);// 将返回的新数组的地址赋值给arr
        System.out.println("arr第二次的地址:"+arr );
        
        // 扩容后重写看效果
        System.out.println("扩容后arr: " );
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] +" ");
        }
    }

    // 这个方法可以将数组长度扩大1倍
    public static int<