Java Array 数组

Java Array 数组

一,数组的介绍

1. 数组的理解(Array)

概念: 是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。
简称: 多个和数据的组合。
Java中的容器: 数组、集合框架: 在内存中对多个数据的存储

2. 数组相关的概念

数据名
数据的元素(即内部存储的多个元素)
数据的下标、角标、下角标、索引、index(即找到指定数组元素所使用的编号)
数组的长度(即数组容器中存储的元素的个数)

3. 数组的特点:

数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
创建数组对象会在内存中开辟一整块连续的空间。占据的空间的大小,取决于数组的长度和数组中元素的类型。
数据中的元素在内存中是依次紧密排列的,有序的。
数组,一旦初始化完成,其长度就是确定的,数据的长度一旦确定,就不能修改。
我们可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快。
数组名中引用的是这块连续空间的首地址。

4. 变量按照数据类型的分类

基本数据类型: byte \ short \ int \ long \ float \ double \ char \ boolean
引用数据类型: 类、数组、枚举、注解、记录

5. 数组的分类

按照数组的类型: 基本数据类型元素的数组; 引用数据类型元素的数组
按照数组的维数来分: 一维数组; 二维数组; …

6. 一维数组的使用(6个基本点)

数组的声明和初始化
调用数组的指定元素
数组的属性: length,表示数组的长度
数组的遍历
数据元素的默认初始化值
一维数组的内存解析(难点)

7. 数组元素的默认初始化值的情况

注意: 以数组的动态初始化方式为例说明。
整型数组元素的默认初始化值: 0
浮点型数组元素的默认初始化值: 0.0
字符型数组元素的默认初始化值: 0 (或理解为’\u0000’)
boolean型数组元素的默认初始化值: false
引用数据类型数据元素的默认初始化值: null

二,一维数组

1. 一维数组功能测试

包含,一维数组的静态初始化和动态初始化,数组元素调用和数组元素赋值,测试了不同类型数组的数组的元素的初始值,还有如何获取数组的长度,以及遍历数组,数组的内存解析。

package Java_Array_one;

/**
 * ClassName: One_array_test
 * Packge: Java_Array_one
 * Description: 一维数组的测试
 *
 * @Author: aex
 * @Create 2024/5/8 14:24
 * @Version 1.0
 */
public class One_array_test_1 {
    public static void main(String[] args) {
        //1.声明数组和数组初始化
        // 静态初始化: 数组变量的赋值与数组元素的赋值操作同时进行。
        double[] prices = new double[]{20.32,43.21,43.22}; // 初始化数组

        // 动态初始化: 数组变量的赋值与数组元素的赋值操作分开进行
        String[] foods = new String[4]; // 初始化数组

        // 其他正确的方式
        int arr[] = new int[4];
        int[] arr1 = {1,2,3};  //类型推断

        // 错误的方式
        //int[] arr2 = new int[3]{1,2,3};  // 不能动态和静态结合
        //int[3] arr3 = new int[];  // 不能把动态的的长度放到前面去

        //2. 数组元素的调用
        //通过下标的方式,获取数组的元素
        System.out.println(prices[0]); // 取出数组的第一个元素

        foods[0] = "拌海蜇";
        foods[1] = "龙须菜";
        foods[2] = "炝冬笋";
        foods[3] = "玉兰片";

        System.out.println(foods[0]);

        //3. 数组的长度: 用来描述数组容器中容量的大小
        // 用length属性来获取数组的长度
        System.out.println(foods.length);
        System.out.println(prices.length);

        //4. 如何遍历数组
        for (int i=0;i<foods.length;i++){
            System.out.print(foods[i]);
        }

        for (int i = 0; i < prices.length; i++) {
            System.out.println(prices[i]);
        }
        System.out.println("-----");
        //5. 数组元素的默认初始化值
        int[] arr3 = new int[3];
        System.out.println(arr3[0]); // 整型数组元素的默认初始化值为 0
        double[] arr4 = new double[3];
        System.out.println(arr4[2]); // 浮点型数组元素的默认初始化值为 0
        boolean[] arr5 = new boolean[3];
        System.out.println(arr5[0]); // 布尔型数组元素的默认初始化值为 false
        char[] arr6 = new char[3];
        System.out.println(arr6[1]); // 字符型数组元素的默认初始化值为 0
        String[] arr7= new String[3];
        System.out.println(arr7[0]); // 引用型数组元素的默认初始化值为 null

        //6. 数组的内存解析
        int[] a1 = new  int[]{1,2,3};
        int[] a2 = a1;
        a2[1] = 10;
        System.out.println(a1[1]);
        System.out.println(a1);  // a1 和 a2 指向的内存地址是同一个
        System.out.println(a2);  // a1 和 a2 指向的内存地址是同一个

        String a3  = "3b07d329";
        int number  = Integer.parseInt(a3,16); // 将16进制转换为十进制,查看内存地址
        System.out.println(number);
    }
}

2. 一维数组案例

(1). 破解房东电话

实现思路: 这里是有两个数组,一个是存着电话的具体数字,一个数字可能被多次使用,比如122345 这里 2 就使用了两次,然后第二个数字就是存着这些号码的索引,比如第一个是1 也就是上面数组的第二个位置,也就是1,第一位号码就是1,然后我们还要定义一个数组 tel 用来接收电话号码,进入循环,初始化条件 i = 0,因为 索引是从0开始的,i < 索引数组的长度,也就是 11 因为电话号码就是 11 位,我们先把 索引都拿到 也就是 index[i] ,然后把每一位的索引对应的号码都拿到 arr[index[i]] 把每一位号码放到 tel 也就是存号码的数组里,tel[i] = arr[index[i]] 最后for循环遍历这个 tel 数组就可以了。
注意:这个题考察的点是 两个数组间索引和值的对应 tel[i] = arr[index[i]];

/**
         * 案例:"破解" 房东电话
         *
         * 升景坊单间短期出租4个月,550元/月(水电煤公摊,网费35元/月),空调,卫生间,厨房齐全,屋内均是IT行业人员
         * 所以要求求租者最好是同行或者刚毕业的年轻人,爱干净,安静
         * */
        int[] arr = new int[]{9,1,0,3,6,9,8}; // 用来存具体的号码
        int[] index = new int[]{1,0,3,4,2,4,5,5,3,6,4}; //用来存号码的位数对应的具体号码的索引跟上面的数组对应
        int[] tel = new int[11]; // 定义一个变量 int 数组 用来接收电话号码
        for (int i = 0;i < index.length;i++){
//            int value = index[i];
            tel[i] = arr[index[i]];   // 将电话号码存入这个数组中
        }

        for (int j = 0;j < tel.length;j++){ //遍历这个数组,输出电话号码
            System.out.print(tel[j]);
        }

结果输出
在这里插入图片描述

(2). 输出英文星期几

思路:用一个数组存放一周七天的单词,相当于是输入一个数字然后拿到对应的 week 数组里的索引的元素,像是这样,System.out.print(week[0]) 这样拿到的就是 第一个元素也就是 Monday,我们的索引是从 0 开始的,用一个变量 day 来接收输入的数字,if(day >=1 && day <= 7){System.out.print(week[day - 1])} 之所以要这样写是因为,数字肯定是要 大于等于1并且小于等于7,然后 索引是从0开始,如果我们 输入数字1要星期一,那应该是 1-1 索引 0 刚好对应星期一。

/**
 * 案例:输出英文星期几
 * 用一个数组,保存星期一到星期天的7个英文单词,从键盘输入1-7,显示对应的单词
 * {"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"}
 * */
String[] week = new String[]{"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
Scanner scan = new Scanner(System.in);
System.out.print("请输入数值(1-7):");
for (;;){
    int day = scan.nextInt();
    if(day >= 1 || day <= 7){
        System.out.println(week[day - 1]);
    }else{
        System.out.println("你输入的数据有误!");
        break;
    }
}

结果输出
在这里插入图片描述

(3). 学生考试等级划分

思路:首先第一步是 输入学生的人数,由这个人数来决定数组的长度,第二步就是循环,这里面要输入每一个学生的成绩,定义一个变量 cj 来接收每一个学生的成绩,然后赋值给 用来存放成绩的数组,然后获取 这些学生成绩里面的最大值,Arrays.stream(arr_score).max(); 直接用这个 api,最后一步就是遍历这个成绩数组,并且将最大值与每一位学生的成绩做对比来划分等级。

 /**
         * 案例:学生考试等级划分
         * 从键盘读入学生成绩,找出最高分,并输出学生成绩等级
         *  成绩 >= 最高分 - 10  等级为: 'A'
         *  成绩 >= 最高分 - 20  等级为: 'B'
         *  成绩 >= 最高分 - 30  等级为: 'C'
         *  其余  等级为: 'D'
         *
         *  先读入学生人数,根据人数创建int数组,存放学生成绩
         * */

        //1. 从键盘输入学生的人数,根据人数,创建数组(动态初始化)
        Scanner scan1 = new Scanner(System.in);
        System.out.print("请输入学生人数:");
        int count = scan1.nextInt();
        int[] arr_score = new int[count]; // 根据人数创建动态数组

        //2. 根据提示,依次输入学生成绩,并将成绩保存在数组元素中
        for (int i = 0;i < arr_score.length;i++){
            System.out.print("请输入第"+(i + 1) + "位学生成绩:");
            int cj = scan1.nextInt();
            arr_score[i] = cj;
        }

        //3. 获取学生成绩的最大值
        OptionalInt max_score = Arrays.stream(arr_score).max();
        System.out.println(max_score.getAsInt());

        //4. 遍历数组元素,根据学生成绩与最高分的差值,得到每个学生的等级,并输出成绩和等级
        for (int i = 0;i< arr_score.length;i++){
            if(arr_score[i] >= max_score.getAsInt() - 10){
                System.out.println("学生成绩为:" + arr_score[i] + "等级为: 'A'");
            }else if (arr_score[i] >= max_score.getAsInt() - 20){
                System.out.println("学生成绩为:" + arr_score[i] + "等级为: 'B'");
            } else if (arr_score[i] >= max_score.getAsInt() - 30) {
                System.out.println("学生成绩为:" + arr_score[i] + "等级为: 'C'");
            }else{
                System.out.println("学生成绩为:" + arr_score[i] + "等级为: 'D'");
            }
        }

结果输出
在这里插入图片描述

(4). 最大子序列和

思路:我们定义了一个数组,如何确定这个数组中的最大子序列和是什么样的,定义两个变量,一个是 当前序列的和,另外一个是最大的子序列和,他们的初始值,都是数组的第一个元素,然后对比数组的当前元素 Math.max(nums[i], currentSum + nums[i]) 当前数组元素和当前序列加上当前元素,看他们之中谁大,然后就返回当前子序列,然后拿当前的子序列和跟最大序列和比较,目前的最大子序列和还是初始值,返回他们之中大的那个 maxSum = Math.max(maxSum, currentSum);,这样最大子序列和就更新了,然后往后一直这么比较,最后返回最大子序列和。

package Java_Array_algorithm;

/**
 * ClassName: MaxSubArray
 * Packge: Java_Array_algorithm
 * Description: 案例:求数组的最大子序列和 (我们这里使用卡丹算法实现)
 * 输入一个整型数组,数组里有正数也有负数,数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和
 * 求所有子数组和的最大值,要求时间复杂度为O(n)
 * 例如:输入的数组为1,-2,3,10,-4,7,2,-5 最大子数组为: 3,10,-4,7,2 最大子数组的和为 18
 *
 * @Author: aex
 * @Create 2024/5/21 10:10
 * @Version 1.0
 */
public class MaxSubArray {
    public static int maxSubArray(int[] nums) {
        // 初始化当前子序列和以及最大子序列和为数组的第一个元素
        int currentSum = nums[0]; // 这是我们当前数组的序列和,初始值为数组的第一个元素
        int maxSum = nums[0]; // 这是我们设置的最大子序列的数组和初始值也是数组的第一个元素

        // 遍历数组中的其余元素
        for (int i = 1; i < nums.length; i++) {
            // 更新当前子序列和,决定是否延续当前子序列或开始新的子序列
            currentSum = Math.max(nums[i], currentSum + nums[i]);

            // 更新最大子序列和
            maxSum = Math.max(maxSum, currentSum); // 如果当前子序列和比最大子序列和还要大,则更新最大子序列和
        }

        return maxSum;
    }

    public static void main(String[] args) {
        // 测试数据
        int[] nums = {1,-2,3,10,-4,7,2,-5};
        // 输出结果
        System.out.println(maxSubArray(nums));  // 应输出6,对应子序列[4, -1, 2, 1]
    }
}

在这里插入图片描述

三,二维数组

1. 二维数组功能测试

包含,二维数组的静态初始化和动态初始化,数组元素调用和数组元素赋值,测试了不同类型数组的数组的元素的初始值,还有如何获取数组的长度,以及遍历数组,数组的内存解析。

package Java_Array_one;

/**
 * ClassName: Two_array_test1
 * Packge: Java_Array_one
 * Description:
 *
 * @Author: aex
 * @Create 2024/5/10 12:46
 * @Version 1.0
 */
public class Two_array_test1 {
    public static void main(String[] args) {
        //1. 数组的声明与初始化
        // 方式1: 静态初始化: 数组变量的赋值和数组元素的赋值同时进行
        int[][] arr2 = new int[][]{{1,2,3},{4,5,},{6,7,8}};
        //方式2: 动态初始化1: 数组变量的赋值和数组元素的赋值分开进行
        String[][] arr3 = new String[3][4];
        //方式2: 动态初始化2
        String[][] arr4 = new String[2][]; // 可以确定外层数组的长度,然后里层数组的长度不设置,每一个数组灵活可变\

        //其它正确的写法
        int[] arr5[] = new int[][]{{1,2,3},{4,5,},{6,7,8}}; // 建议不要这么写
        int[][] arr6 = {{1,2,3},{4,5,},{6,7,8}};   //类型推断 写在一行的时候,可以不用 new

        //2. 数组元素的调用
        //针对arr2来说,外层元素{1,2,3},{4,5},{6,7,8,9}  内层元素: 1,2,3,4,5,6,7,8,9
        //调用内层元素
        System.out.println(arr2[0][0]); // 1
        System.out.println(arr2[2][1]); // 7
        //调用外层元素
        System.out.println(arr2[2]); //[I@4eec7777 存的是一个内存地址

        //测试arr3,arr4
        arr3[0][1] = "Tom";  //因为上面是动态初始化,没有赋值,所以我们得给他赋个值
        System.out.println(arr3[0][1]); //Tom
        System.out.println(arr3[0]);  //[Ljava.lang.String;@3b07d329 打印的内存地址

        arr4[0] = new String[4]; //String[][] arr4 = new String[2][] 是这么定义的,他的内层没有定义长度,所以我们这里的定义不然没有地址
        arr4[1] = new String[3]; // 这是第二个 外层数组,定义他的内层长度为3。 arr4[0] = new String[4] 第一个外层数组定义长度为 3
        arr4[0][2] = "1.0";
        System.out.println(arr4[0][2]); // "1.0"

        //3. 数组的长度
        System.out.println(arr2.length); //他打印的是外层数组的长度{{1,2,3},{4,5,},{6,7,8}} 长度为3
        System.out.println(arr2[0].length); // 外层第一个数组的长度 长度为 3
        System.out.println(arr2[1].length); // 外层第二个数组的长度 长度为 2
        System.out.println(arr2[2].length); // 外层第三个数组的长度 长度为 1

        //4. 如何遍历数组
        for (int i = 0; i < arr2.length; i++) {
            for (int j = 0; j < arr2[i].length; j++) { //j < arr2[i].length 这里是小于 arr2[0] 长度为3,也就是小于3, arr2[1] 长度为2,也就是小于2, arr2[2] 长度为1,也就是小于1
                System.out.print(arr2[i][j] + " ");
            }
            System.out.println();
        }

        //5. 数组元素的默认初始化值
        //5.1 动态初始化1
        int[][] arr1 = new int[3][4];
        //外层元素默认值:
        System.out.println(arr1[0]); //[I@568db2f2 打印的内存地址

        //内层元素默认值:
        System.out.println(arr1[0][0]); // 0 内层的默认初始化值和 一维数组的一样

        //5.2 动态初始化2
        int[][] arr10 = new int[3][];
        //外层元素默认值:
        System.out.println(arr10[0]); // null
        //内层元素默认值:
        System.out.println(arr10[0][0]); //报错java.lang.NullPointerException 空指针异常,没有找到 arr10[0][0] 因为没有定义内层长度
    }
}

2. 二维数组案例

(1). 获取arr数组中所有元素的和

思路:只需要将这个二维数组遍历一下,然后定义一个遍历去 += 接收 值就可以了。

package Java_Array_one;

/**
 * ClassName: Two_array_test2
 * Packge: Java_Array_one
 * Description: 二维数组案例: 获取arr数组中所有元素的和
 * 提示:使用 for 的循环嵌套就可以了
 *
 * @Author: aex
 * @Create 2024/5/13 16:16
 * @Version 1.0
 */
public class Two_array_test2 {
    public static void main(String[] args) {
        int[][] arr = new int[][]{{3,5,8},{12,9},{7,0,6,4}};
        int sum = 0;
        for(int i = 0;i < arr.length;i++){  // 这里控制的是外层数组的长度
            for(int j = 0;j < arr[i].length;j++){ //这里控制的是内层数组的长度
                System.out.print(arr[i][j] + "\t");
                sum += arr[i][j];
            }
        }

        System.out.println("数组的和为:" + sum);


    }
}

在这里插入图片描述

(2). 判断二维数组赋值是否正确(判断题)

注意:判断两个数组是否能赋值,有两个条件因素,第一个 他们的类型必须相同,第二个他们的维数必须相同,

package Java_Array_one;

/**
 * ClassName: Two_array_test3
 * Packge: Java_Array_one
 * Description: 二维数组练习案例
 * 案例: 声明:int[] x,y[]; 在给x,y变量赋值以后,以下选项允许通过编译的是: x: 一维int[] y: 二维int[][] 注意:想要赋值首先得类型一样,维数一样
 *  a) x[0] = y;   这个是错的
 *  b) y[0] = x;   这个是对的
 *  c) y[0][0] = x; 这个是错的维数不一样
 *  d) x[0][0] = y; 这个是错的,x 是一维数组
 *  e) y[0][0] = x[0]; 这个是对的 将x 数组的第一个元素赋值给 y数组的第一个外层元素里的第一个内存元素
 *  f) x = y;  这个不行,一个是二维的一个是一维的
 *
 *  提示:
 *  一维数组: int[] x 或者int x[]
 *  二维数组: int[][] y 或者 int[] y[] 或者 int y[][]
 *
 *
 * @Author: aex
 * @Create 2024/5/14 14:38
 * @Version 1.0
 */
public class Two_array_test3 {
    public static void main(String[] args) {
        int[] arr1 = new int[10];
        byte[] arr2 = new byte[20];

        //arr1 = arr2; //编译不通过,原因 : int[],byte[] 是两种不同的引用变量

        System.out.println(arr1); // [I@4eec7777 他们不只存了地址值,还有类型值 所以无法赋值
        System.out.println(arr2); //[B@3b07d329

        int[][] arr3 = new int[3][2];
        //arr3 = arr1; //编译不通过  他们的维度都不一样,一个是一维数组,一个是二维数组
        arr3[0] = arr1;  //这个可以因为这样他们都是一维数组
        System.out.println(arr3[0]); //[I@4eec7777
        System.out.println(arr1); //[I@4eec7777
    }
}
(3). 员工的职位编号替换为职位名称

思路:我们首先在循环里将 employess[i][0] 的第一个元素进行判断,如果他是10,11,12,13 那么替换为具体的职位名称。然后下面再来一个循环,将这个二维数组给遍历出来,就可以了。

package Java_Array_one;

/**
 * ClassName: Two_array_test4
 * Packge: Java_Array_one
 * Description: 二维数组将员工的职位编号替换为职位名称
 *
 * @Author: aex
 * @Create 2024/5/14 15:38
 * @Version 1.0
 */
public class Two_array_test4 {
    public static void main(String[] args) {
        String[][] employess = {
                {"10","1","段誉","22","3000"},
                {"13","2","令狐冲","32","18000","15000","2000"},
                {"11","3","任我行","23","7000"},
                {"11","4","张三丰","24","7300"},
                {"12","5","周芷若","28","10000","5000"},
                {"11","6","赵敏","22","6800"},
                {"12","7","张无忌","29","10800","5200"},
                {"13","8","韦小宝","30","19800","15000","2500"},
                {"12","9","杨过","26","9800","5500"},
                {"11","10","小龙女","21","6600"},
                {"11","11","郭靖","25","7100"},
                {"12","12","黄蓉","27","9600","4800"}
        };
        // 其中"10"代表普通职员,"11" 代表程序员,"12"代表设计师,"13"代表架构师。显示效果如下面
        for(int i =0;i < employess.length;i++){
            for(int j = 0;j<employess[i].length;j++){
                if(employess[i][0].equals("10")){
                    employess[i][0] = "普通职员\t";
                } else if (employess[i][0].equals("11")) {
                    employess[i][0] = "程序员\t";
                }else if (employess[i][0].equals("12")) {
                    employess[i][0] = "设计师\t";
                }else if (employess[i][0].equals("13")) {
                    employess[i][0] = "架构师\t";
                }
            }
        }

        System.out.println("员工类型\t\t编号\t姓名\t\t年龄\t薪资\t奖金\t股票");
        for (int i = 0;i<employess.length;i++){
            for (int j = 0;j<employess[i].length;j++){
                System.out.print(employess[i][j] + "\t");
            }
            System.out.println();
        }


    }
}

在这里插入图片描述

四,数组的常见算法

1. 特征值统计,数组元素赋值,数组复制,数组反转

(1). 数值型数组特征值统计

这里的特征值涉及到:平均值,最大值,最小值,总和等。
思路:首先定义自动数组长度,然后给每一个元素随机赋值,然后遍历这个数组,定义一个变量来接收这个数组所有元素的和,Arrays.stream(array).max().getAsInt() 数组中的最大值,Arrays.stream(array).min().getAsInt() 数组中的最小值,像最大值最小值都可以用API来获取,然后平均值,我们直接用数组元素的和除以数组长度就可以了。sum / array.length

package Java_Array_algorithm;

import java.util.Arrays;
import java.util.Scanner;

/**
 * ClassName: array_test1
 * Packge: Java_Array_algorithm
 * Description: 案例: 定义一个int型的一维数组,包含10个元素,分别赋一些随机整数,然后求出所有元素的最大值,
 * 最小值,总和,平均值,并输出出来s
 *
 * 要求:所有的随机数都是两位数:[10,99]
 * 提示:要求 [a,b] 范围内的随机数:int(Math.random() * (b - a + 1)) + a; -> int(Math.random() * (99 - 10 + 1)) + 10;
 *
 * @Author: aex
 * @Create 2024/5/14 16:36
 * @Version 1.0
 */
public class array_test1 {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int sum = 0;
        System.out.print("请输入数组长度:");
        int lengths = scan.nextInt();
        int[] array = new int[lengths];
        for (int i = 0; i < array.length; i++) {
            array[i] = (int) (Math.random() * (99 - 10 + 1)) + 10;  //赋值为随机值
        }

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

        System.out.println("数组的最大值:" + Arrays.stream(array).max().getAsInt());
        System.out.println("数组的总和:" + sum);
        System.out.println("数组的最小值:" + Arrays.stream(array).min().getAsInt());
        System.out.println("数组的平均值:" + sum / array.length);
    }
}

在这里插入图片描述

(2).数组元素的赋值(实际开发中,遇到的场景比较多)

思路:首先我们定义了一个数组arr1,然后遍历了这个数组看他是什么样子有哪些元素,然后我们定义了第二个元素,我们将第一个数组赋值给第二个元素,array2 = array1; 然后我们修改第二个元素的 偶元素索引的值,修改为跟索引一样,比如索引0的位置,值就为0,索引2位置,值就为2,奇数索引就不变,这时候我们再次遍历输出 arr1 和 arr2 发现,他们一摸一样,因为之前将 arr1 赋值给arr2 他们现在指向的地址是一样的,可以相当于是一个数组。

package Java_Array_algorithm;

/**
 * ClassName: array_test6
 * Packge: Java_Array_algorithm
 * Description: 数组的赋值
 *
 * @Author: aex
 * @Create 2024/5/15 16:55
 * @Version 1.0
 */
public class array_test6 {
    public static void main(String[] args) {
        int[] array1= new int[]{2,3,5,7,11,13,17,19};
        int[] array2;
        // 显示array1的内容
        for(int i = 0;i<array1.length;i++){
            System.out.print(array1[i] + "\t");
        }
        System.out.println();
        //赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)
        array2 = array1; // 将 array1 的值赋值给 array2  此时他们的地址已经一样了,不算复制
        for(int i = 0;i<array1.length;i++){
            if(i % 2 == 0){
                array2[i] = i;    //如果array2数组中索引为偶数,那么使其元素等于缩引值
            }
            System.out.print(array2[i] + "\t");
        }
        System.out.println();

        //打印出array1
        for(int i = 0;i<array1.length;i++){   // array1 和 array2 已经是一个内存地址了,所以打印的结果和array2一样
            System.out.print(array1[i] + "\t");
        }

    }
}

在这里插入图片描述

(3).数组的复制

思路:我们还是有两个数组,arr1 和 arr2 我们将 arr1 遍历出来,然后 array2[i] = array1[i]; 将 arr1 的每一个元素赋值给 arr2 ,这样就相当于复制过去了,而不是整个将内存地址都给赋值过去了,然后复制完之后我们再对arr2的偶元素索引进行修改就好了,这是再遍历 arr1 和 arr2 发现他们不一样,arr1 没有修改。

package Java_Array_algorithm;

/**
 * ClassName: array_test6_2
 * Packge: Java_Array_algorithm
 * Description: 数组的复制
 *
 * @Author: aex
 * @Create 2024/5/15 17:13
 * @Version 1.0
 */
public class array_test6_2 {
    public static void main(String[] args) {
        int[] array1= new int[]{2,3,5,7,11,13,17,19};
        int[] array2;
        // 显示array1的内容
        for(int i = 0;i<array1.length;i++){
            System.out.print(array1[i] + "\t");
        }
        System.out.println();
        //赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)
        array2 = new int[array1.length]; // 要复制就得造一个新的
        for (int i = 0;i< array1.length;i++){
            array2[i] = array1[i]; // 这样一个一个赋值过去,就复制了
        }
        System.out.println();
        System.out.println("array2数组:");
        for (int i = 0;i<array2.length;i++){
            if(i % 2 ==0){
                array2[i] = i;
            }
            System.out.print(array2[i] + "\t");

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

    }
}

在这里插入图片描述
4.数组的反转
思路:下面介绍了三种方法,这里我们主要说一下第二种方法,我们在循环里设置两个变量,一个 i 为数组的第一个元素的位置,一个 j 是数组最后一个元素的位置,然后 循环条件是 i < j 因为,思路是数组的第一个元素和最后一个元素交换,数组的第二个元素和倒数第二个元素交换,交换到中间的时候如果只剩下一个元素那么也不用交换了,所以 i < j 当他们是一样的时候说明已经相等了,可以结束循环了,然后 i++ j-- ,一个从前面往后面走,一个从后面往前面走。

package Java_Array_algorithm;

import java.util.Arrays;

/**
 * ClassName: array_test7
 * Packge: Java_Array_algorithm
 * Description: 案例:如何实现数组元素的反转存储?你有几种方法
 *
 * @Author: aex
 * @Create 2024/5/16 9:28
 * @Version 1.0
 */
public class array_test7 {
    public static void main(String[] args) {
        int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67};
        //方式1
//        //因为这里有11个元素,第一个和最后一个交换,第二个和倒数第二个交换,然后中间的第六个自己交换,
//        // 所以我们要循环次数是11/2 = 5次,不然的话,循环不会停止他要循环十一次,又把之前的循环回去,所以循环数组一半的次数就合适了
//        for (int i = 0;i<arr.length/2;i++){   //
//            int temp = arr[i];  // temp = arr[0];
//            arr[i] = arr[arr.length - 1 - i];  // arr[0] = arr[11 - 1 - 0] 也就是刚好是数组的最后一个元素和第一个元素交换
//            arr[arr.length -1 -i] = temp;   // 然后将第一个元素和最后一个元素交换了
//        }
        //方式2
        //这里设置了两个变量,第一个i是第一个元素开始,第二j是最后一个元素开始,i++,j--
        //循环条件设置为 i < j,因为i 在不断变大,j在不断变小,如果当他们两个一样的时候不用交换因为就剩中间那一个了,i < j就可以了
        for (int i= 0,j = arr.length - 1;i < j;i++,j--){
            //交换 arr[i] 和 arr[j] 的位置
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }

        //方式3(不推荐)
//        int[] arr2= new int[arr.length];
//        for(int i = arr.length - 1; i>=0 ;i--){
//            arr2[arr2.length - 1- i] = arr[i];  //赋值给arr2数组,将arr数组的第一个元素赋值给arr2数组的最后一个元素
//        }
//        arr = arr2;  //然后将arr2数组赋值给arr就达到了数组翻转

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

在这里插入图片描述

2. 数组扩容与缩容,数组元素查找,数组排序

(1).数组的扩容

思路:将第一个数组赋值给第二个数组的时候,第二个数组动态初始化,写成这样 int[] arr2 =new int[arr.length*2];,然后我们先将第一个数组的元素复制过去,在第一个数组的最后一个元素后面,添加三个元素,进行赋值就好了。这样就做到了数组扩容一倍,然后添加三个元素。

package Java_Array_algorithm;

/**
 * ClassName: array_test8
 * Packge: Java_Array_algorithm
 * Description: 案例:数组的扩容
 *  现有数组 int[] arr = new int[]{1,2,3,4,5} 现将数组长度扩容1倍,并将10,20,30,三个数据添加到arr数组中,如何操作?
 *
 * @Author: aex
 * @Create 2024/5/16 10:17
 * @Version 1.0
 */
public class array_test8 {
    public static void main(String[] args) {
        int[] arr = new int[]{1,2,3,4,5};
        int[] arr2 =new int[arr.length*2];
        for(int i = 0;i<arr.length;i++){
            arr2[i] = arr[i];
        }
        arr2[arr.length] = 10;
        arr2[arr.length+1] = 20;
        arr2[arr.length+2] = 30;
        arr = arr2;

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

    }
}

在这里插入图片描述

(2).数组的缩容

思路:java 数组的长度一旦确定就不能更改,所以我们也只能 new 一个新的数组来接收,分为两部分,比如我们要删除 arr1 索引4 位置的元素,然后我们把索引4之前的元素遍历出来进行赋值,然后是第二部分,是索引4开始,然后到 数组的最后,arr[i] 比如为 4 那么等于 arr[i+1] 相当于是把后面的值赋到这个位置,就把这个位置的数据给删除了,这里要注意下标越界,因为这个理 i+ 1了,所以循环条件 要 -1, i < arr.length - 1

package Java_Array_algorithm;

/**
 * ClassName: array_test9
 * Packge: Java_Array_algorithm
 * Description:案例:数组的缩容
 * 现有数组 int[] arr = int[]{1,2,3,4,5,6,7} 需删除数组中索引为4的元素。
 *
 * @Author: aex
 * @Create 2024/5/16 10:30
 * @Version 1.0
 */
public class array_test9 {
    public static void main(String[] args) {
        int[] arr = new int[]{1,2,3,4,5,6,7};

        int deleteIndex = 4; // 也就是说我们要在索引为4的地方更改
//
//        //方式1:不新建数组
//        for(int i = deleteIndex;i < arr.length - 1;i++){
//            arr[i] = arr[i+1]; //这里i是从4开始的,然后我们要让4等于5,5等于6,这样做到删除索引4这个元素
//        }
//        arr[arr.length - 1] = 0; //将最后一位设置为 0,相当于将索引为4的元素删除了,然后后面的元素往前移,然后最后一位就变成了0
        //方式2:新建数组,新的数组的长度比原有数组的长度少1个
        int[] arr2 = new int[arr.length - 1];
        for(int i = 0;i< deleteIndex;i++){ //分成两部分,这是要删除索引以前的元素
            arr2[i] = arr[i];
        }
//        arr = arr2;
        for(int i = deleteIndex;i<arr.length - 1;i++){ //第二部分从索引删除的地方开始往后移
            arr2[i] = arr[i+1];  // 值是要后面的
        }

        for (int i =0;i< arr2.length;i++){
            System.out.print(arr2[i] + "\t");  // 1	2	3	4	6	7
        }
    }
}

在这里插入图片描述

(3).数组元素的查找
顺序查找:

思路:就是把数组遍历一遍,加一个if 判断,如果 arr[i] 当前索引元素为我们的目标值,就找到了,
在加一个遍历 isFlag 标记,标记我们找没找到,循环完了判断一下这个变量,就可以看出找没找到。

 优点: 好实现,容易想到
    缺点: 时间复杂度要低一点
  package Java_Array_algorithm;

/**
 * ClassName: arrat_test10
 * Packge: Java_Array_algorithm
 * Description: 数组的排序算法
 * 案例:线性查找
 *  定义数组:int[] arr1 = new int[]{34,54,3,2,65,7,34,5,76,34,67};
 *  查找元素5是否在上述数组中出现过?如果出现,输出对应的索引值
 * @Author: aex
 * @Create 2024/5/16 15:00
 * @Version 1.0
 */
public class array_test10 {
    public static void main(String[] args) {
        int[] arr1 = new int[]{34,54,3,2,65,7,34,5,76,34,67};
        boolean isFlas = true;
        for(int i = 0;i<arr1.length;i++){
            if(arr1[i] == 5){
                System.out.println("索引为:" +i +"索引值为:"+arr1[i]);
                isFlas = false; // 找到了就退出,如果没找到就不退出一直为true,如果找到最后都是true,说明没有这个元素
                break;
            }
        }
        if (isFlas){
            System.out.println("不好意思没找到");
        }

    }
}

在这里插入图片描述

二分查找:
优点: 速度快,时间复杂度低
缺点: 数组必须是有序的
package Java_Array_algorithm;

import java.awt.geom.FlatteningPathIterator;
import java.time.chrono.MinguoChronology;

/**
 * ClassName: array_test11
 * Packge: Java_Array_algorithm
 * Description: 案例: 二分查找
 *  定义数组: int[] arr2 = new int[]{2,4,5,8,12,15,19,26,37,49,51,66,89,100};
 *  查找元素5是否在上述数组中出现过? 如果出现,输出对应的索引值
 * @Author: aex
 * @Create 2024/5/16 15:59
 * @Version 1.0
 */
public class array_test11 {
    public static void main(String[] args) {
        int[] arr2 = new int[]{2,4,5,8,12,15,19,26,37,49,51,66,89,100};
        int target = 6; // 查找的目标值
        boolean isFlag  = false; //判断是否找到指定元素
        //二分查找中三个元素
        int left = 0;
        int right = arr2.length - 1;
        while (left <= right){
            int mid = (left + right) / 2; // 中间值,这个一定要放在循环里面,因为每次的中间值都不一样,直到找到了就退出
            if(arr2[mid] == target){
                System.out.println("找到了" + target + "索引位置是:" + mid);
                isFlag = true;
                break;
            } else if (target > arr2[mid]) {
                left = mid + 1;
            } else if (target < arr2[mid]) {
                right = mid - 1;
            }
        }

        if (!isFlag){  //如果找到了,我们上面标记为true了,如果这里如果他为true没有进去的话,说明没有找到
            System.out.println("没找到");
        }

    }
}

在这里插入图片描述

(4).数组的排序

排序算法的衡量标准: ① 时间复杂度(最重要)② 空间复杂度 ③ 稳定性
排序的分类: 内部排序(内存中排序); 外部排序(外部存储设备+内存)
内部排序的具体算法:10 种
我们需要关注的几个排序算法:

冒泡排序:最简单,需要轻松手写,时间复杂度: O(n^2)
快速排序:最快的,开发中默认选择的排序方式:掌握快速排序的实现思路;时间复杂度 O(nlogn)

冒泡排序

思路:按照的元素相互比较,第一趟会把最大的那个元素排出来,第二趟会把第二大的那个元素排出来,如果上一个元素比下一个元素大,那么他们就交换元素,例如有 5个元素,那么他们理论上会交换 4 次,所以 循环的初始值为0,循环条件为 i< arr.length -1 ,用两层 for 循环实现。因为内层循环相当于是实现一次元素交换,内层for循环第一次循环完,最大的元素排在了最后,外层循环控制次数。

package Java_Array_algorithm;

/**
 * ClassName: array_test12
 * Packge: Java_Array_algorithm
 * Description: 案例:使用冒泡排序,实现整型数组元素的排序操作
 *  比如:int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67};
 *
 * @Author: aex
 * @Create 2024/5/17 15:17
 * @Version 1.0
 */
public class array_test12 {
    public static void main(String[] args) {
        int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67};
//        for(int i = 0;i < arr.length -1;i++){  // 这样只执行了一轮,只把最大的那个数排出来了
//            if(arr[i] > arr[i+1]){
//                int temp = arr[i];
//                arr[i] = arr[i+1];
//                arr[i+1] = temp;
//            }
//        }

        for(int i = 0;i< arr.length -1;i++){   // 如果有5个元素,那个把最大的
            for(int j =0;j < arr.length - 1;j++){  //这样相当于是排了一次,把最大的那个排出来了,
                if(arr[j] > arr[j+1]){ //如果上一个元素比下一个元素大,那么他们就交换元素
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }

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

在这里插入图片描述

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值