第五章 Java数组(知识点与企业真题)

一、知识点

1.数组的概述

  • 数组,就可以理解为多个数据的组合。
  • 是程序中的容器:数组、集合框架(第12章,List、Set、Map)。
  • 数组存储的数据的特点:依次紧密排列的、有序的、可以重复的。
  • 此时的数组、集合框架都是在内存中对多个数据的存储。
  • 数组的其它特点:一旦初始化,其长度就是确定的、不可更改的。

基本语法的知识点:

1. 数组的理解(Array)

概念:是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。

简称:地多个数据的组合

Java中的容器:数组、集合框架(第12章)。在内存中对多个数据的存储。

2.几个相关的概念
> 数据名
> 数组的元素(既内部存储的多个元素)
> 数组的下标、角标、小角标、索引、index(即找到指定数组元素所使用的编号)
> 数组的长度(既数组容器中存储的元素的个数)

3.数组的特点:
> 数组中的元素在内存中是依次紧密排列的,有序的。
> 数组,属于引用数据类型的变量。数组的元素,既可以是基本数据类型,也可以是引用数据类型。
> 数组,一旦初始化完成,共长度就确定了,并且长度不可更改。
> 创建数组对象会扎起内存中开辟一整块‘连续的空间’。占据的空间的大小,取决于数组的长度和数组中元素的类型。

4. 复习:变量按章数据类型的分类
4.1 基本数据类型: byte \ short \ int \ long \ char \ boolean \ float \ double
4.2 引用数据类型: 类、数组、接口、枚举、注解、记录

5. 数组的分类
5.1 按照元素的类型:基本数类型元素的数组,引用数据类型元素的数组
5.2 按照元素的维数来分:一维数组,二维数组,...

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

7. 数组元素的默认初始化值的情况
注意:以数组的动态初始化方式为例说明。

> 整型数组元素的默认初始化值:0
> 浮点型数组元素的默认初始化值:0.0
> 字符型数组元素的默认初始化值:0 (或理解为'\u0000')
> boolean型数组元素的默认初始化值:false
> 引用数据类型数组元素的默认初始化值:null

8. 一维数组的内存解析
8.1 Java中的内存结构是如何划分的?(主要关心JVM的运行时内存环境)
> 将内存区域划分为5个部分:程序计数器、虚拟机栈、本地方法栈、堆、方法区

> 与目前数组相关的内存结构:   比如:int[] arr = new int[]{1,2,3};
    > 虚拟机栈:用于存放方法中声明的变量。比如:arr
    > 堆:用于存放数组的实体(即数组中的所有元素)。比如:1,2,3

8.2 举例:具体一维数组的代码的内存解析

基本语法的代码1:

package com.atguigu1.one;

/**
 * ClassName: OneArraryTest
 * Package: com.atguigu1.one
 * Description: 一维数组的基本使用
 *
 * @Author 随心油条
 * @Create 2024/1/25 9:52
 * @Version 1.0
 */
public class OneArraryTest {
    public static void main(String[] args) {
//        1. 数组的声明与初始化
//        复习:变量的定义格式:数据类型 变量名 = 变量值
        int num1 = 10;
        int num2; //声明
        num2 = 20; //初始化

//        1.1 声明数组
        double[] prices;
//        1.2 数组的初始化
//        静态初始化:数组变量的赋值与数组元素的赋值操作同时进行。
        prices = new double[]{20.32,43.21,43.22};
//        这里不能使用
//        princes = {20.32,43.21,43.22};

//        String[] foods;
//        foods = new String[]{"拌海蜇","龙须菜","炝冬笋","玉兰片"};

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

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

//        错误的方式
//        int[] arr2 = new int[4]{1,2,3,4};//既有动态,又有静态 报错的原因为:同时使用维表达式和初始化创建数组是非法的
//        int[3] arr3 = new int[]; //声明数组元素个数只能从后面的[]中声明

//        2.数组元素的调用
//        通过角标的方式,获取数组的元素
//        角标的范围从0开始,到数组的长度-1结束
        System.out.println(prices[0]);
        System.out.println(prices[2]);
//        System.out.println(prices[4]);//异常:ArrayIndexOutOfBoundsException

        foods[0] = "拌海蜇";
        foods[1] = "龙须菜";
        foods[2] = "炝冬笋";
        foods[3] = "玉兰片";
//        foods[4] = "酱茄子";//异常:ArrayIndexOutOfBoundsException

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

//        4.如何遍历数组
//        System.out.println(foods[0]);
//        System.out.println(foods[1]);
//        System.out.println(foods[2]);
//        System.out.println(foods[3]);

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

基本语法的代码2:

package com.atguigu1.one;

/**
 * ClassName: OneArraryTest1
 * Package: com.atguigu1.one
 * Description: 一维数组的基本使用(承接OneArrayTest.java)
 *
 * @Author 随心油条
 * @Create 2024/1/25 10:47
 * @Version 1.0
 */
public class OneArraryTest1 {
    public static void main(String[] args) {

        //5. 数组元素的默认初始化值
//        整形数组元素的默认初始化值:0
        int[] arr1 = new int[3];
        System.out.println(arr1[0]);//输出为0


//        整形数组元素的默认初始化值:0
        short[] arry2 = new short[2];
        for (int i = 0; i < arry2.length; i++) {
            System.out.println(arry2[i]); //输出0
        }

//        浮点型数组元素的默认初始化值:0.0
        double[] arry3 = new double[4];
        System.out.println(arry3[1]); //输出0.0

//        字符型数组元素的默认初始化值:0 (或理解为'\u0000')
        char[] arry4 = new char[2];
        System.out.println(arry4[1]);
        if (arry4[1] == 0){
            System.out.println("aaaa");  //输出aaaa
        }
        if (arry4[1] == '0'){
            System.out.println("bbbb");
        }
        if (arry4[1] == '\u0000'){
            System.out.println("cccc");  //输出cccc
        }
        System.out.println((arry4[0] + 1)); //输出1
//        boolean型数组元素的默认初始化值:
        boolean[] arry5 = new boolean[2];
        System.out.println(arry5[0]); //输出false

//        引用数据类型数组元素的默认初始化值:null 而不是 "null"
        String[] arry6 = new String[5];
        System.out.println(arry6[0]); // 输出null
        if (arry6[1] == null){
            System.out.println("1111"); //输出1111
        }
        if (arry6[1] == "null"){
            System.out.println("2222");
        }

        //6.数组的内存解析
        int[] a1 = new int[]{1,2,3};
//      int a2 = a1; //会报错:不兼容的类型: int[]无法转换为int
        int[] a2 = a1; //没有new就没有新开辟空间,就用的a1的地址
        a2[1] = 10;
        System.out.println(a1[1]); //输出10
        System.out.println(a1); //输出数组a1的地址[I@776ec8df    其中[表示数组,@表示地址,776ec8df表示地址的数值,且为十六进制
        System.out.println(a2); //输出数组a2的地址[I@776ec8df

    }
}

案例1:

package com.atguigu1.one.exer1;

/**
 * 案例:"破解"房东电话
 *
 * 升景坊单间短期出租4个月,550元/月(水电煤公摊,网费35元/月),空调、卫生间、厨房齐全。屋内均是IT行业人士,喜欢安静。
 * 所以要求来租者最好是同行或者刚毕业的年轻人,爱干净、安静。
 *
 */

/**
 * ClassName: ArrayExer
 * Package: com.atguigu1.one.exer1
 * Description: 案例
 *
 * @Author 随心油条
 * @Create 2024/1/25 14:07
 * @Version 1.0
 */
public class ArrayExer {
    public static void main(String[] args) {
        int[] arr = new int[]{ 8, 6, 1, 0, 3};
        int[] index = new int[]{ 2, 4, 3, 1, 0, 4, 1, 2, 1, 4, 2};

        String tel = "";

        for (int i = 0; i < index.length; i++) {
            int value = index[i];
            tel += arr[value];
        }
        System.out.println("联系方式: " + tel);//输出:18013820100
    }
}

案例2:

需求:
案例:输出英文星期几

用一个数组,保持星期一到星期天的7个英语但粗,从键盘输入1-7,显示对应的单词
{"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"}

拓展:一年12个月的存储

用一个数组,保存12个月的英语单词,从键盘输入1-12,显示对应的单词。
{"January","February","March","April","May","June","July","August","September","October","November","December"}
代码:
package com.atguigu1.one.exer2;

import java.util.Scanner;

/**
 * ClassName: ArrayExer
 * Package: com.atguigu1.one.exer2
 * Description: 案例:输出英文星期几
 *
 * 用一个数组,保存星期一到星期天的7个英语单词,从键盘输入1-7,显示对应的单词
 * {"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"}
 *
 * @Author 随心油条
 * @Create 2024/1/25 14:15
 * @Version 1.0
 */

public class ArrayExer02 {
    public static void main(String[] args) {
//        定义包含7个单词的数组
        String[] weeks = new String[]{ "Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};

//        从键盘获取指定的数值,使用Scanner
        Scanner input = new  Scanner(System.in);
        System.out.print("请输入1-7的整数: ");
        int chooes = input.nextInt();
//        没有定义数组的时候就这么做,现在定义数组了就换种方式.
//        switch (chooes) {
//            case 1:
//                System.out.println("您的结果为: " + weeks[0]);
//                break;
//            case 2:
//                System.out.println("您的结果为: " + weeks[1]);
//                break;
//            case 3:
//                System.out.println("您的结果为: " + weeks[2]);
//                break;
//            case 4:
//                System.out.println("您的结果为: " + weeks[3]);
//                break;
//            case 5:
//                System.out.println("您的结果为: " + weeks[4]);
//                break;
//            case 6:
//                System.out.println("您的结果为: " + weeks[5]);
//                break;
//            case 7:
//                System.out.println("您的结果为: " + weeks[6]);
//                break;
//        }

//        针对获取的数据进行判断即可
        if (chooes < 1 || chooes > 7){
            System.out.println("您的输入有误!!");
        }else {
            System.out.println("您的结果为:" + weeks[chooes - 1]);
        }

        input.close();
    }
}

案例3:

需求:
案例:学生考试等级划分

从键盘读入学生成绩,找出最高分,并输出学生成绩等级。
	成绩>=最高分-10    等级为’A’
	成绩>=最高分-20    等级为’B’
	成绩>=最高分-30    等级为’C’
	其余              等级为’D’

提示:先读入学生人数,根据人数创建int数组,存放学生成绩。
代码1:
package com.atguigu1.one.exer3;

import java.util.Scanner;

/**
 * ClassName: ArrayExer03
 * Package: com.atguigu1.one.exer3
 * Description: 从键盘读入学生成绩,找出最高分,并输出学生成绩等级。
 *
 *  * 成绩>=最高分-10    等级为’A’
 *  * 成绩>=最高分-20    等级为’B’
 *  * 成绩>=最高分-30    等级为’C’
 *  * 其余              等级为’D’
 *
 * @Author 随心油条
 * @Create 2024/1/25 14:35
 * @Version 1.0
 */
public class ArrayExer03 {
    public static void main(String[] args) {

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

        //2.根据提示,依次输入学生成绩,并将成绩保存在数组元素中
        System.out.println("请依次输入学生成绩: ");
        int[] scores = new int[studentNum];
        for (int i = 0; i < studentNum; i++) {
            int score = input.nextInt();
            scores[i] =score;
        }


        //3.获取学生成绩的最大值
        int maxScore = scores[0];
        for (int i = 1; i < scores.length; i++){
            if (maxScore < scores[i]){
                maxScore = scores[i];
            }
        }
        System.out.println("学生成绩最大值为: " + maxScore);

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

        //关闭资源
        input.close();
        }
}
代码2:
package com.atguigu1.one.exer3;

import java.util.Scanner;

/**
 * ClassName: ArrayExer03_1
 * Package: com.atguigu1.one.exer3
 * Description: 基于ArrayExer03的改进
 *
 * @Author 随心油条
 * @Create 2024/1/25 15:26
 * @Version 1.0
 */
public class ArrayExer03_1 {
    public static void main(String[] args) {

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

        //2.根据提示,依次输入学生成绩,并将成绩保存在数组元素中
        System.out.println("请依次输入学生成绩: ");
        int[] scores = new int[studentNum];
        int maxScore = scores[0];//scores[0]=0
        for (int i = 0; i < studentNum; i++) {
            int score = input.nextInt();
            scores[i] =score;
            //3.获取学生成绩的最大值
            if (maxScore < scores[i]){
                maxScore = scores[i];
            }
        }

        System.out.println("学生成绩最大值为: " + maxScore);

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

        //关闭资源
        input.close();
    }
}

2.一维数组的使用(重要)

基本语法的知识点:

1. 二维数组的理解

- 对于二维数组的理解,可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。
- 其实,从数组底层的运行机制来看,其实没有多维数组。
- 概念:数组的外层元素;数组的内层元素

2. 二维数组的使用(6个基本点)
> 数组的声明和初始化
    int[] arr = new int[10];
    String[] arr1 = new String[]{"Tom", "Jerry"};
> 调用数组的指定元素:使用角标、索引、index
    >index从0开始!
> 数组的属性:length,表示数组的长度
> 数组的遍历
> 数组元素的默认初始化值
> 二维数组的内存解析(难)
    前提:在main()中声明变量:int[] arr = new int[]{1,2,3};
    >虚拟机栈:main()作为一个栈帧,压入栈空间中。在main()栈帧中,存储着arr变量。arr记录着数组实体的首地址值。
    >堆:数组实体存储在堆空间中。

3. 二维数组元素的默认初始化值
3.1 动态初始化方式1:(比如:int[][] arr = new int[3][4])

1)外层元素,默认存储地址值。
2)内层元素,默认与一维数组元素的不同类型的默认值规定相同。
    > 整型数组元素的默认初始化值:0
    > 浮点型数组元素的默认初始化值:0.0
    > 字符型数组元素的默认初始化值:0 (或理解为'\u0000')
    > boolean型数组元素的默认初始化值:false
    > 引用数据类型数组元素的默认初始化值:null

3.2 动态初始化方式2:(比如:int[][] arr = new int[3][])
1)外层元素,默认存储null,因为内层不存在,所有外层存储内存的地址为默认值,而数组是引用型数据,默认值为null。
2)内层元素,不存在的。如果调用会报错(NullPointerException)

基本语法的代码1:

package com.atguigu2.two;

/**
 * ClassName: TwoArrayTest
 * Package: com.atguigu2.two
 * Description:
 *
 * @Author 随心油条
 * @Create 2024/1/25 16:13
 * @Version 1.0
 */
public class TwoArrayTest {
    public static void main(String[] args) {

        // 1.数组的声明与初始化
        //复习一维数组的声明与初始化
        //方式1:静态初始化:数组变量的赋值和数组元素的赋值同时进行
        int[] arr1 = new int[]{1,2,3};
        int[] arr2 = {1,2,3};
        //二维数组的声明与初始化
        //方式1:静态初始化:数组变量的赋值和数组元素的赋值同时进行
        int[][] arr4 = new int[][]{{1,2,3},{4,5},{6,7,8,9}};
        int[][] arr6 = {{1,2,3},{4,5},{6,7,8,9}};

        //方式2:动态初始化:数组变量的赋值和数组元素的赋值分开进行
        int[] arr3 = new int[3];
        //二维数组的声明与初始化
        //方式2:动态初始化:数组变量的赋值和数组元素的赋值分开进行
        String[][] arr5 = new String[3][4];
        double[][] arr7 = new double[3][];

        // 其他正确的写法:
        int arr8[][] = new int[][]{{1,2,3},{4,5},{6,7,8,9}};
        int[] arr9[] = new int[][]{{1,2,3},{4,5},{6,7,8,9}};
        int arr10[][] = {{1,2,3},{4,5},{6,7,8,9}};
        String arr11[][] = new String[3][4];

        //错误的写法:
//        int[][] arr12 = new int[3][3]{{1,2,3},{4,5,6},{7,8,9}};
//        int[3][3] arr10 = new int[][]{{1,2,3},{4,5,6},{7,8,9}};

        // 2.数组元素的调用
        // 针对于arr4来说,外层元素{1,2,3},{4,5},{6,7,8,9} 内层元素:1,2,3,4,5,6,7,8,9
        // 调用内层元素
        System.out.println(arr4[0][2]);//输出3
        System.out.println(arr4[2][3]);//输出9

        //调用外层元素
        System.out.println(arr4[0]);//输出[I@776ec8df  其中[表示数组,@表示数组,776ec8df表示地址的数值

        //测试arr5,arr6
        arr5[0][1] = "Tom";
        System.out.println(arr5[0][1]); //输出Tom
        System.out.println(arr5[0]); // 输出[Ljava.lang.String;@4eec7777

        arr7[0] = new double[3];
        arr7[0][0] = 1.0;

        // 3.数组的长度
        System.out.println(arr4.length);//输出3
        System.out.println(arr4[0].length);//输出3
        System.out.println(arr4[1].length);//输出2
        System.out.println(arr4[2].length);//输出4

        // 4.如何遍历二元数组的每个元素
        for (int i = 0; i < arr4.length; i++) {
            for (int j = 0; j < arr4[i].length; j++) {
                System.out.print(arr4[i][j] + "\t");
            }
            System.out.println();
        }

    }
}

基本语法的代码1:

package com.atguigu2.two;

/**
 * ClassName: TwoArrayTest1
 * Package: com.atguigu2.two
 * Description:
 *
 * @Author 随心油条
 * @Create 2024/1/25 16:13
 * @Version 1.0
 */
public class TwoArrayTest1 {
    public static void main(String[] args) {
        //5. 数值元素的默认初始化值
        //以动态初始化方式1说明:

        //整形数组元素的默认初始化值分内外层
        int[][] arr1 = new int[3][2];
        //外层元素默认值:
        System.out.println(arr1[0]);//输出地址[I@776ec8df
        System.out.println(arr1[1]);//输出地址[I@4eec7777

        //内层元素默认值:
        System.out.println(arr1[0][0]);//输出整形的默认值0

        //布尔类型数组元素的默认初始化值分内外层
        boolean[][] arr2 = new boolean[3][2];
        //外层元素默认值:
        System.out.println(arr2[0]);//输出地址[Z@3b07d329

        //内层元素默认值:
        System.out.println(arr2[0][0]);//输出布尔类型的默认值false

        //字符串类型数组元素的默认初始化值分内外层
        String[][] arr3 = new String[3][2];
        //外层元素默认值:
        System.out.println(arr3[0]);//输出地址[Ljava.lang.String;@41629346

        //内层元素默认值:
        System.out.println(arr3[0][0]);//输出数组的默认值null
//        ********************************
        //以动态初始化方式2说明:

        //整形数组元素的默认初始化值分内外层
        int[][] arr4 = new int[3][];
        //外层元素默认值:
        System.out.println(arr4[0]);//输出数组的默认值null
        //内层元素默认值:
//        System.out.println(arr4[0][0]);//没有分配内存空间,所以会报错:NullPointerException

        //字符串类型数组元素的默认初始化值分内外层
        String[][] arr5 = new String[3][];
        //外层元素默认值:
        System.out.println(arr5[0]);//输出数组的默认值null

        //内层元素默认值:
//        System.out.println(arr5[0][0]);//没有分配内存空间,所以会报错:NullPointerException
    }
}

案例1:



案例1:获取arr数组中所有元素的和。

提示:使用for的嵌套循环即可。

利用二维数组遍历求和,二维数组如图所示。

package com.atguigu2.two.exer1;

/**
 * ClassName: ArrayExer01
 * Package: com.atguigu2.two.exer1
 * Description: 案例1:获取arr数组中所有元素的和
 *
 *提示:使用for的嵌套循环即可。
 *
 * @Author 随心油条
 * @Create 2024/1/25 18:51
 * @Version 1.0
 */
public class ArrayExer01 {
    public static void main(String[] args) {
        //初始化数组:使用静态初始化
        int[][] arr1 = new int[][]{{3,5,8},{12,9},{7,0,6,4}};
        int sum = 0;
        for (int i = 0; i < arr1.length; i++) {
            for (int j = 0; j < arr1[i].length; j++) {
                sum += arr1[i][j];
            }
        }
        System.out.println("总和为: " + sum);
    }
}

案例2:


案例:声明:int[] x,y[]; 在给x,y变量赋值以后,以下选项允许通过编译的是:

声明: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;
e)    y[0][0] = x[0];
f)    x = y;

提示:
一维数组:int[] x  或者int x[]
二维数组:int[][] y 或者  int[] y[]  或者 int  y[][]
package com.atguigu2.two.exer2;

/**
 * ClassName: ArrayExer02
 * Package: com.atguigu2.two.exer2
 * Description: 声明:int[] x,y[]; 在给x,y变量赋值以后,以下选项允许通过编译的是:
 *
 * 声明: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;
 * e)    y[0][0] = x[0];
 * f)    x = y;
 *
 * 提示:
 * 一维数组:int[] x  或者int x[]
 * 二维数组:int[][] y 或者  int[] y[]  或者 int  y[][]
 *
 * @Author 随心油条
 * @Create 2024/1/25 18:57
 * @Version 1.0
 */
public class ArrayExer02 {
    public static void main(String[] args) {

        // = :赋值符号.
        int i = 10;
        int j = i;
        byte b = (byte)i; //强制类型转换

        long l = i; //自动类型提升

        //举例:数组
        int[] arr2 = new int[10];
        byte[] arr3 = new byte[20];
//        arr2 = arr3;编译不通过,原因:int[]和byte[]是两种不同类型的引用变量

        System.out.println(arr2);//输出[I@776ec8df
        System.out.println(arr3);//输出[B@4eec7777

        //声明
        int[] x = new int[1];
        int[][] y = new int[1][1];
        //a)    x[0] = y;
//        x[0] = y;//报错:不兼容的类型: int[][]--->y 无法转换为 int--->x[0]

        //b)    y[0] = x;
        y[0] = x; //可以通过编译,因为都是int[]类型

        //c)    y[0][0] = x;
//        y[0][0] = x;//报错:不兼容的类型: int[]--->x 无法转换为 int--->y[0][0]

        //d)    x[0][0] = y;
//        x[0][0] = y;//报错:需要数组--->y, 但找到int--->x[0][0]

        //e)    y[0][0] = x[0];
        y[0][0] = x[0];//可以通过编译,因为都是int类型

        //f)    x = y;
//        x = y;报错:不兼容的类型: int[][]--->y 无法转换为 int[]--->x
    }
}

案例3:

需求:

案例:二维数组存储数据,并遍历

String[][] employees = {
    {"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"代表架构师。输出显示效果如图。

代码:
package com.atguigu2.two.exer3;

/**
 * ClassName: ArrayExer03
 * Package: com.atguigu2.two.exer3
 * Description: 案例:二维数组存储数据,并遍历
 *
 * String[][] employees = {
 *     {"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"代表架构师。显示效果如图。
 *
 * @Author 随心油条
 * @Create 2024/1/25 19:07
 * @Version 1.0
 */
public class ArrayExer03 {
    public static void main(String[] args) {
        String[][] employees = {
                    {"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"}
  };
        System.out.println("员工类型" + "\t" + "编号" + "\t" + "姓名" + "\t\t" + "年龄" + "\t" + "薪资" + "\t" + "\t奖金" + "\t" + "\t股票");

        for (int i = 0; i < employees.length; i++) {
                switch (employees[i][0]) {
                    case "10":
                        employees[i][0] = "普通职员";
                        break;
                    case "11":
                        employees[i][0] = "程序员";
                        break;
                    case "12":
                        employees[i][0] = "设计师";
                        break;
                    case "13":
                        employees[i][0] = "架构师";
                        break;
                }

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

3.二维数组的使用(难点)

基本语法的知识点:


【数组的常见算法1】

1. 数值型数组特征值统计
这里的特征值涉及到:平均值、最大值、最小值、总和等

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

3. 数组的复制

4. 数组的反转

案例1:

需求:


案例:定义一个int型的一维数组,包含10个元素,分别赋一些随机整数,然后求出所有元素的最大值,最小值,总和,平均值,
并输出出来。

要求:所有随机数都是两位数:[10,99]
提示:求[a,b]范围内的随机数: (int)(Math.random() * (b - a + 1)) + a;
package com.atguigu3.common_algorithm.exer1;

/**
 * ClassName: ArrayExer01
 * Package: com.atguigu3.common_algorithm.exer1
 * Description: 定义一个int型的一维数组,包含10个元素,分别赋一些随机整数,然后求出所有元素的最大值,最小值,总和,平均值,并输出出来。
 *
 * 要求:所有随机数都是两位数:[10,99]
 * 提示:求[a,b]范围内的随机数: (int)(Math.random() * (b - a + 1)) + a;
 *
 * @Author 随心油条
 * @Create 2024/1/25 20:22
 * @Version 1.0
 */
public class ArrayExer01 {
    public static void main(String[] args) {

        //1.动态初始化方式创建数组
        int[] arr = new int[10];

        //2.通过循环给数组元素赋值
        for (int i = 0; i < arr.length; i++){
            arr[i] = (int) (Math.random() * 90) + 1;
        }

        //将所有的数遍历出来
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }

        //3.1求最大值
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if(max < arr[i]){
                max = arr[i];
            }
        }
        System.out.println("\n最大值为: " + max);//最大值为: 70

        //3.2求最小值
        int min = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if(min > arr[i]){
                min = arr[i];
            }
        }
        System.out.println("最小值为: " + min);//最小值为: 6

        //3.3求总和
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        System.out.println("总和为: " + sum);//总和为: 317

        //3.4求平均
        int avgValue = 0;
        avgValue = sum/(arr.length);
        System.out.println("平均值为: " + avgValue);//平均值为: 31

    }
}

案例2:

需求:


案例:评委打分

分析以下需求,并用代码实现:

(1)在编程竞赛中,有10位评委为参赛的选手打分,分数分别为:5,4,6,8,9,0,1,2,7,3

(2)求选手的最后得分(去掉一个最高分和一个最低分后其余8位评委打分的平均值)
package com.atguigu3.common_algorithm.exer2;

/**
 * ClassName: ArrayExer02
 * Package: com.atguigu3.common_algorithm.exer2
 * Description: 评委打分
 *
 * 分析以下需求,并用代码实现:
 *
 * (1)在编程竞赛中,有10位评委为参赛的选手打分,分数分别为:5,4,6,8,9,0,1,2,7,3
 *
 * (2)求选手的最后得分(去掉一个最高分和一个最低分后其余8位评委打分的平均值)
 *
 * @Author 随心油条
 * @Create 2024/1/25 20:37
 * @Version 1.0
 */
public class ArrayExer02 {
    public static void main(String[] args) {
        int[] scores = new int[]{5,4,6,8,9,0,1,2,7,3};
        //声明三个特征值
        int sum = 0;
        int max = scores[0];
        int min = scores[0];

        //求总和,最大值,最小值
        for (int i = 0; i < scores.length; i++) {
            sum += scores[i];
            if (max < scores[i]){
                max = scores[i];
            }
            if (min > scores[i]){
                min = scores[i];
            }
        }

        //求平均
        int avrgScore = (sum-max-min)/(scores.length-2);
        System.out.println("评委们打的平均分为: " + avrgScore);
    }
}

案例3:

需求:


案例:使用二维数组打印一个 10 行杨辉三角。

   提示:
   1. 第一行有 1 个元素, 第 n 行有 n 个元素
   2. 每一行的第一个元素和最后一个元素都是 1
   3. 从第三行开始, 对于非第一个元素和最后一个元素的元素。即:
   yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];

   4.输出效果如图所示。

代码:
package com.atguigu3.common_algorithm.exer3;

/**
 * ClassName: YangHuiTest
 * Package: com.atguigu3.common_algorithm.exer3
 * Description: 使用二维数组打印一个 10 行杨辉三角。
 *
 * 提示:
 *    1. 第一行有 1 个元素, 第 n 行有 n 个元素
 *    2. 每一行的第一个元素和最后一个元素都是 1
 *    3. 从第三行开始, 对于非第一个元素和最后一个元素的元素。即:
 *    yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];
 *
 * @Author 随心油条
 * @Create 2024/1/25 21:05
 * @Version 1.0
 */
public class YangHuiTest {
    public static void main(String[] args) {
        //1. 创建二维数组
        int[][] YangHui= new int[10][];//注意定义里面的数值和索引的偏移量是不一样的

        //2.使用循环结构,初始化外层数组元素
        for (int i = 0; i < YangHui.length; i++) {
            YangHui[i] = new int[i + 1];//因为这里i只能到9,而新定义new int[i + 1]这里的(i + 1)要为10

            //3. 给数组的元素赋值

            //3.1 给数组每行的首末元素赋值为1
            YangHui[i][i] = YangHui[i][0] = 1;
//            if (i >= 2){
                for (int j = 1; j < YangHui[i].length - 1; j++) { //j从每行的第2个元素开始(所以最开始初始化索引为1),到倒数第2个元素结束
                    YangHui[i][j] = YangHui[i - 1][j - 1] + YangHui[i - 1][j];
//                }
            }
        }
        for (int i = 0; i < YangHui.length; i++) {
            for (int j = 0; j < YangHui[i].length; j++) {
                System.out.print(YangHui[i][j] + "\t");
            }
            System.out.println();
        }
    }
}

案例4:

需求:


案例:复制、赋值

使用简单数组
(1)创建一个名为ArrayTest的类,在main()方法中声明array1和array2两个变量,他们是int[]类型的数组。
(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
(3)显示array1的内容。
(4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。
(5)打印出array1。

思考:array1和array2是什么关系?
【answer】array1和array2是两个变量,共同指向了堆空间中的同一个数组结构。即二者的地址值相同。

拓展:修改题目,实现array2对array1数组的复制
代码1:
package com.atguigu3.common_algorithm.exer4;

/**
 * ClassName: ArrayExer04
 * Package: com.atguigu3.common_algorithm.exer4
 * Description: 案例:数组的赋值
 *
 * 使用简单数组
 * (1)创建一个名为ArrayTest的类,在main()方法中声明array1和array2两个变量,他们是int[]类型的数组。
 * (2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
 * (3)显示array1的内容。
 * (4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。
 * (5)打印出array1。
 *
 * 思考:array1和array2是什么关系?
 * 【answer】array1和array2是两个变量,共同指向了堆空间中的同一个数组结构。即二者的地址值相同。
 *
 * 拓展:修改题目,实现array2对array1数组的复制
 *
 * @Author 随心油条
 * @Create 2024/1/25 21:42
 * @Version 1.0
 */
public class ArrayExer04 {
    public static void main(String[] args) {
        //使用简单数组
        //(1)创建一个名为ArrayExer04的类,在main()方法中声明array1和array2两个变量,他们是int[]类型的数组。
        int[] array1,array2;

        //(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
        array1 = new int[]{2,3,5,7,11,13,17,19};

        //(3)显示array1的内容。
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");//输出2	3	5	7	11	13	17	19
        }
        System.out.println();//换行

        //(4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。
        array2 = array1;
        System.out.println(array1);//输出[I@58372a00
        System.out.println(array2);//输出[I@58372a00
        for (int i = 0; i < array1.length; i++) {
            if(i % 2 == 0){
                array1[i] = i;
            }
        }
        //(5)打印出array1。
        System.out.println();//换行
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");//输出0	3	2	7	4	13	6	19
        }
    }
}
代码2:
package com.atguigu3.common_algorithm.exer4;

/**
 * ClassName: ArrayExer04_1
 * Package: com.atguigu3.common_algorithm.exer4
 * Description: 数组的复制
 *
 * @Author 随心油条
 * @Create 2024/1/25 21:42
 * @Version 1.0
 */
public class ArrayExer04_1 {
    public static void main(String[] args) {
        //使用简单数组
        //(1)创建一个名为ArrayExer04的类,在main()方法中声明array1和array2两个变量,他们是int[]类型的数组。
        int[] array1;
        int[] array2;


        //(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
        array1 = new int[]{2,3,5,7,11,13,17,19};

        //(3)显示array1的内容。
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");//输出2	3	5	7	11	13	17	19
        }
        System.out.println();//换行

        //(4)复制array1数组给array2,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。

        array2 = new int[array1.length];//没有这个语句会报这个错:可能尚未初始化变量array2,所以我们用动态初始化,通过array1的长度来初始化array2
        for (int i = 0; i < array1.length; i++) {
            array2[i] = array1[i];
        }
        System.out.println(array1);//输出[I@58372a00
        System.out.println(array2);//输出[I@4dd8dc3
        for (int i = 0; i < array1.length; i++) {
            if(i % 2 == 0){
                array1[i] = i;
            }
        }
        //(5)打印出array1。
        System.out.println();//换行
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");//输出2	3	5	7	11	13	17	19
        }
    }
}
内存解析1:

内存解析2:

案例5:

需求:


案例:
定义数组:int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67};
如何实现数组元素的反转存储?你有几种方法。

反转数组图示:

对称数组图示:

代码:
package com.atguigu3.common_algorithm.exer5;

/**
 * ClassName: ArrayExer05
 * Package: com.atguigu3.common_algorithm.exer5
 * Description: 案例:元素反转,对称数组
 *
 * 定义数组:int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67};
 * 如何实现数组元素的反转存储?你有几种方法。
 *
 * @Author 随心油条
 * @Create 2024/1/25 21:55
 * @Version 1.0
 */
public class ArrayExer05 {
    public static void main(String[] args) {
        //1. 定义数组:
        int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67};

        int temp;


        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t"); //数组在转换之前输出一次,输出结果34	54	3	2	65	7	34	5	76	34	67
        }
        //方式1:(推荐)
//        for (int i = 0; i < arr.length/2; i++) {
//            交互arr[i] 与 arr[arr.length - 1 - i]位置的元素
//            temp = arr[i];
//            arr[i] = arr[arr.length - 1 - i];
//            arr[arr.length - 1 -i] = temp;
//        }

        //方式2:(推荐)
        for (int i = 0, j = arr.length - 1 - i; i < j; i++, j--) {
            //交互arr[i] 与 arr[j]位置的元素
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }

//        //方式3:(不建议,一,开辟一个新空间,二,遍历的次数太多)
//        int[] newArray = new int[arr.length];
//        for (int i = arr.length - 1; i >= 0; i--) {
//            newArray[arr.length - 1 - i] = arr[i];
//        }
//        arr = newArray;

        System.out.println();
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t"); //数组在转换之前输出一次,输出结果67	34	76	5	34	7	65	2	3	54	34
        }


        //对称数组的解决办法:
        boolean isFlag = true;
        int[] arr1 = new int[]{1,2,3,4,5,4,3,2,1};
        for (int i = 0,j = arr1.length - 1; i < j; i++, j--) {
            if (arr1[i] != arr1[j]){
                isFlag = false;
            }
        }
        System.out.println();
        if(isFlag){
            System.out.println("是对称数组");
        }

    }
}

4.数组的常用算法(重要)

基本语法的知识点:




【数组的常见算法2】

1. 数组的扩容与缩容


2. 数组元素的查找
顺序查找:
    > 优点:算法简单;
    > 缺点:执行效率低。执行的时间复杂度O(N)

二分法查找:
    > 优点:执行效率高。执行的时间复杂度O(logN)
    > 缺点:算法相较于顺序查找难一点;前提:数组必须有序

3. 数组的排序

排序算法的衡量标准:① 时间复杂度(最重要) ② 空间复杂度 ③ 稳定性
Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n<sup>2</sup>)<Ο(n<sup>3</sup>)<…<Ο(2<sup>n</sup>)<Ο(n!)<O(n<sup>n</sup>)

排序的分类:内部排序(内存中排序);外部排序(外部存储设备+内存)

内部排序的具体算法:10种。具体的见课件

我们需要关注的几个排序算法:
> 冒泡排序:最简单,需要大家会手写。时间复杂度:O(n^2)
> 快速排序:最快的,开发中默认选择的排序方式;掌握快速排序的实现思路;时间复杂度:O(nlogn)



案例1:

需求:


案例1:数组的扩容:

现有数组 int[] arr = new int[]{1,2,3,4,5};
现将数组长度扩容1倍,并将10,20,30三个数据添加到arr数组中,如何操作?
代码:
package com.stguigu4.search_sort.exer1;

/**
 * ClassName: ArrayExer01_1
 * Package: com.stguigu4.search_sort.exer1
 * Description: 数组的扩容:
 *
 * 现有数组 int[] arr = new int[]{1,2,3,4,5};
 * 现将数组长度扩容1倍,并将10,20,30三个数据添加到arr数组中,如何操作?
 *
 * @Author 随心油条
 * @Create 2024/1/26 9:51
 * @Version 1.0
 */
public class ArrayExer01_1 {
    public static void main(String[] args) {
        //1、初始化,声明int[] arr = new int[]{1,2,3,4,5};
        int[] arr = new int[]{1,2,3,4,5};
        System.out.println("原来数组arr的元素为:" + "\t");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] +  "\t");
        }

        //2、现将数组长度扩容1倍,两种方法
//        int[] arr1 = new int[arr.length * 2];// 使用乘法
        int[] arr1 = new int[arr.length << 1];// 使用左移
        //3、将原有数组中的元素复制到新的数组中并将10,20,30三个数据添加到arr数组中
        for (int i = 0; i < arr.length; i++) {
            arr1[i] = arr[i];
        }
        //4、将10,20,30三个数据添加到新数组中
        arr1[arr.length] = 10;
        arr1[arr.length + 1] = 20;
        arr1[arr.length + 2] = 30;

        //将新的数组的地址赋值给原有的数组变量
        arr = arr1;

        //换行
        System.out.println();

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

案例2:

需求:


案例:数组的缩容:

现有数组 int[] arr={1,2,3,4,5,6,7}。现需删除数组中索引为4的元素。
代码:
package com.stguigu4.search_sort.exer1;

/**
 * ClassName: ArrayExer01_2
 * Package: com.stguigu4.search_sort.exer1
 * Description: 数组的缩容:
 *
 * 现有数组 int[] arr={1,2,3,4,5,6,7}。现需删除数组中索引为4的元素。
 *
 * @Author 随心油条
 * @Create 2024/1/26 10:06
 * @Version 1.0
 */
public class ArrayExer01_2 {
    public static void main(String[] args) {
        //数组的声明和初始化
        int[] arr={1,2,3,4,5,6,7};

        //方法1:推荐
        //采用将索引为5的替换索引为4的元素,而不新创建数组
        for (int i = 4; i < arr.length - 1; i++) {
            arr[i] = arr[i +1];
        }
        for (int i = 0; i < arr.length; i++) {
            //修改最后元素,设置为默认值
            arr[arr.length - 1] = 0;
            System.out.print(arr[i] + "\t");
        }

//        //方法2:
//        //定义一个新数组,新建数组的长度比原有数组的长度少1个
//        int[] newArr = new int[arr.length - 1];
//        //采用将索引为5的替换索引为4的元素,而不新创建数组
//        for (int i = 0; i < arr.length - 1; i++) {
//            newArr[i] = arr[i];
//            if(i >= 4){
//                newArr[i] = arr[i + 1];
//            }
//        }
//        //将新指针指向arr
//        arr = newArr;

        //换行
        System.out.println();

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

    }
}

案例3:

需求:


案例1:线性查找

定义数组:int[] arr1 = new int[]{34,54,3,2,65,7,34,5,76,34,67};
查找元素5是否在上述数组中出现过?如果出现,输出对应的索引值。


案例2:二分法查找

定义数组:int[] arr2 = new int[]{2,4,5,8,12,15,19,26,37,49,51,66,89,100};
查找元素5是否在上述数组中出现过?如果出现,输出对应的索引值。
代码1:二分法查找
package com.stguigu4.search_sort.exer2;

/**
 * ClassName: BinarySearchTest
 * Package: com.stguigu4.search_sort.exer2
 * Description: 二分法查找
 *
 * 定义数组:int[] arr2 = new int[]{2,4,5,8,12,15,19,26,37,49,51,66,89,100};
 * 查找元素5是否在上述数组中出现过?如果出现,输出对应的索引值。
 *
 * @Author 随心油条
 * @Create 2024/1/26 11:22
 * @Version 1.0
 */
public class BinarySearchTest {
    public static void main(String[] args) {
        //1.先定义初始化数组
        int[] arr2 = new int[]{2,4,5,8,12,15,19,26,37,49,51,66,89,100};
        int target = 5;
        //定义一个小旗子
        boolean isFlag = false;//判断是否找到了指定元素

        int head = 0;
        int end = arr2.length - 1;
        int middle;
        while (head <= end){
            middle = (head + end)/2;
            if(target == arr2[middle]){
                System.out.println("恭喜你,找到了元素 " + target);
                isFlag = true;
                break;
            } else if (target > arr2[middle]) {
                head = middle + 1;
            }else {//target < arr2[middle]
                end = middle - 1;
            }
        }
        if (!isFlag){
            System.out.println("很遗憾,没有找到元素 " + target);
        }
    }
}
代码2:线性查找
package com.stguigu4.search_sort.exer2;

/**
 * ClassName: LinearSearchTest
 * Package: com.stguigu4.search_sort.exer2
 * Description: 线性查找
 *
 * 定义数组:int[] arr1 = new int[]{34,54,3,2,65,7,34,5,76,34,67};
 * 查找元素5是否在上述数组中出现过?如果出现,输出对应的索引值。
 *
 * @Author 随心油条
 * @Create 2024/1/26 11:03
 * @Version 1.0
 */
public class LinearSearchTest {
    public static void main(String[] args) {

        //定义、初始化数组
        int[] arr1 = new int[]{34,54,3,2,65,7,34,5,76,34,67};
        int target = 5;
        target = 15;

        //方法1:
       //定义一个小旗子
        boolean isFlag = false;
        int i = 0;
        for (; i < arr1.length; i++) {
            if (arr1[i] == target){
                isFlag = true;
                break;
            }
        }
        if (isFlag){
            System.out.println("找到元素为" + target + ",其索引为:" + i); //输出找到元素为5,其索引为:7
        }else{
                System.out.println("没有找到为" + target + "的元素");
        }

//        //方法2:
//        int i = 0;
//        for (; i < arr1.length; i++) {
//            if (arr1[i] == target){
//                System.out.println("找到元素为" + target + ",其索引为:" + i); //输出找到元素为5,其索引为:7
//                break;
//            }
//        }
//        if (i == arr1.length){
//            System.out.println("没有找到为" + target + "的元素");
//        }

    }
}

案例4:

需求:


案例1:使用冒泡排序,实现整型数组元素的排序操作

比如:int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67};
代码:
package com.stguigu4.search_sort.exer3;

/**
 * ClassName: BubbleSortTest
 * Package: com.stguigu4.search_sort.exer3
 * Description: 案例:使用冒泡排序,实现整型数组元素的排序操作
 *
 * 比如:int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67};
 *
 * @Author 随心油条
 * @Create 2024/1/26 14:30
 * @Version 1.0
 */
public class BubbleSortTest {
    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; i++) {
            System.out.print(arr[i] + "\t");
        }

        //实现冒泡功能
        for (int j = 0; j < arr.length; j++) {
//            for (int i = 0; i < arr.length - 1; i++) {//这样也可以,每一个数都比arr.length次
            for (int i = 0; i < arr.length - 1 - j; i++) {//这种方法每轮可以少j次
                if (arr[i] > arr[i + 1]){
                    //交换arr[i] 和 arr[i + 1]
                    int temp = arr[i];
                    temp = arr[i + 1];
                    arr[i + 1] = arr[i];
                    arr[i] = temp;
                }
            }
        }

        //排序好了之后在进行
        System.out.println();//换行
        //先输出一下原数组
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
    }
}

案例5:

需求:


案例:使用快速排序,实现整型数组元素的排序操作

比如:int[] data = { 9, -16, 30, 23, -30, -49, 25, 21, 30 };

代码:
package com.stguigu4.search_sort.exer3;

/**
 * 快速排序
 * 通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,
 * 则分别对这两部分继续进行排序,直到整个序列有序。
 *
 * @author 尚硅谷-宋红康
 * @create 13:18
 *
 */
public class QuickSort {
	public static void main(String[] args) {
		int[] data = {9, -16, 30, 23, -30, -49, 25, 21, 30};
		System.out.println("排序之前:");
		for (int i = 0; i < data.length; i++) {
			System.out.print(data[i]+" ");
		}

		quickSort(data);//调用实现快排的方法

		System.out.println("\n排序之后:");
		for (int i = 0; i < data.length; i++) {
			System.out.print(data[i]+" ");
		}
	}

	public static void quickSort(int[] data) {
		subSort(data, 0, data.length - 1);
	}

	private static void subSort(int[] data, int start, int end) {
		if (start < end) {
			int base = data[start];
			int low = start;
			int high = end + 1;
			while (true) {
				while (low < end && data[++low] - base <= 0)
					;
				while (high > start && data[--high] - base >= 0)
					;
				if (low < high) {
					//交换data数组[low]与[high]位置的元素
					swap(data, low, high);
				} else {
					break;
				}
			}
			//交换data数组[start]与[high]位置的元素
			swap(data, start, high);

			//经过代码[start, high)部分的元素 比[high, end]都小

			//通过递归调用,对data数组[start, high-1]部分的元素重复刚才的过程
			subSort(data, start, high - 1);
			//通过递归调用,对data数组[high+1,end]部分的元素重复刚才的过程
			subSort(data, high + 1, end);
		}
	}

	private static void swap(int[] data, int i, int j) {
		int temp = data[i];
		data[i] = data[j];
		data[j] = temp;
	}
}

5.Arrays工具类的使用

基本语法的知识点:


数组工具类Arrays的使用 (熟悉)

1. Arrays类所在位置: 处在java.util包下

2. 作用:
java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索)的各种方法。

案例1:

package com.stguigu5.arrays;

import java.util.Arrays;

/**
 * ClassName: ArraysTest
 * Package: com.stguigu5.arrays
 * Description: 数组工具类Arrays的使用 (熟悉)
 *
 * 1. Arrays类所在位置: 处在java.util包下
 *
 * 2. 作用:
 * java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索)的各种方法。
 *
 * @Author 随心油条
 * @Create 2024/1/26 15:17
 * @Version 1.0
 */
public class ArraysTest {
    public static void main(String[] args) {
        //1. boolean equals(int[] a,int[] b): 比较两个数组的元素是否依次相等
        int[] arr1 = new int[]{1,2,3,4,5};
        int[] arr2 = new int[]{1,2,3,4,5};
//        arr2 = new int[]{1,2,3,5,4};
        System.out.println(arr1 == arr2);//false,这里是存什么比什么,存地址就比地址

        boolean isEquals = Arrays.equals(arr1,arr2);//这里是调用Arrays.equals方法,比较arr1,arr2的内容是否相等
        System.out.println(isEquals);//true

        //2. String toString(int[] a):输出数组元素信息。
        System.out.println(arr1);//输出arr1的地址,[I@776ec8df
        System.out.println(Arrays.toString(arr1));//输出arr1中的元素[1, 2, 3, 4, 5]

        //3. void fill(int[] a,int val):将指定值填充到数组之中。
        Arrays.fill(arr1,10);
        System.out.println(Arrays.toString(arr1));//输出[10, 10, 10, 10, 10]

        //4. void sort(int[] a):使用快速排序算法实现的排序
        int[] arr3 = new int[]{34,54,3,2,65,7,34,5,76,34,67};
        Arrays.sort(arr3);//自动排序
        System.out.println(Arrays.toString(arr3));//[2, 3, 5, 7, 34, 34, 34, 54, 65, 67, 76]

        //5. int binarySearch(int[] a,int key):二分查找
        //使用前提:当前数组必须是有序的

        //方式1:
        int index = Arrays.binarySearch(arr3,5);
        System.out.println("元素5的索引为:" + index);//输出元素5的索引为2

        //方式2:
        int index1 = Arrays.binarySearch(arr3,15);
        if(index1 >= 0){
            System.out.println("找到了,索引值为:" + index1);
        }else {
            System.out.println("很遗憾,未找到该元素!");//输出很遗憾,未找到该元素!
        }
    }
}

6.数组中的常见异常

基本语法的知识点:




1. 数组的使用中常见的异常小结

> 数组角标越界的异常:ArrayIndexOutOfBoundsException
> 空指针的异常:NullPointerException


2. 出现异常会怎样?如何处理?
> 一旦程序执行中出现了异常,程序就会终止执行。
> 针对异常提供的信息,修改对应的代码,避免异常再次出现。


案例1:

package com.atguigu6.exception;

/**
 * ClassName: ArrayExceptionTest
 * Package: com.atguigu6.exception
 * Description: 测试数组中常见的异常
 *
 * 1. 数组的使用中常见的异常小结
 *
 * > 数组角标越界的异常:ArrayIndexOutOfBoundsException
 * > 空指针的异常:NullPointerException
 *
 *
 * 2. 出现异常会怎样?如何处理?
 * > 一旦程序执行中出现了异常,程序就会终止执行。
 * > 针对异常提供的信息,修改对应的代码,避免异常再次出现。
 *
 * @Author 随心油条
 * @Create 2024/1/26 15:52
 * @Version 1.0
 */
public class ArrayExceptionTest {
    public static void main(String[] args) {
        //1. 数组角标越界的异常:
        int[] arr = new int[10];
        //角标的有效范围:0、1、2、...、9
//        System.out.println(arr[10]);//报错:ArrayIndexOutOfBoundsException
//        System.out.println(arr[-1]);//报错:ArrayIndexOutOfBoundsException

        //2. 空指针异常:
        //情况1:
        int[] arr1 = new int[10];

        arr1 = null;
//        System.out.println(arr1[0]);//报错:NullPointerException

        //情况2:
        int[][] arr2 = new int[3][];
        arr2[0] = new int[10];//此行代码不存在时,下一行代码就出现异常。
        System.out.println(arr2[0][0]);//报错:NullPointerException

        //情况3:
        String[] arr3 = new String[4];//arr3是一个对象,当对象为null时,调用方法就报空指针的错
//        System.out.println(arr3[0].toString());//报错:NullPointerException
    }
}

二、企业真题

1. 数组有没有length()这个方法? String有没有length()这个方法?

        数组没有length(),是length属性。

        String有length()

2. 有数组int[] arr,用Java代码将数组元素顺序颠倒。

package com.atguigu3.common_algorithm.exer5;

/**
 * ClassName: ArrayExer05
 * Package: com.atguigu3.common_algorithm.exer5
 * Description: 案例:元素反转,对称数组
 *
 * 定义数组:int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67};
 * 如何实现数组元素的反转存储?你有几种方法。
 *
 * @Author 随心油条
 * @Create 2024/1/25 21:55
 * @Version 1.0
 */
public class ArrayExer05 {
    public static void main(String[] args) {
        //1. 定义数组:
        int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67};

        int temp;


        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t"); //数组在转换之前输出一次,输出结果34	54	3	2	65	7	34	5	76	34	67
        }
        //方式1:(推荐)
//        for (int i = 0; i < arr.length/2; i++) {
//            交互arr[i] 与 arr[arr.length - 1 - i]位置的元素
//            temp = arr[i];
//            arr[i] = arr[arr.length - 1 - i];
//            arr[arr.length - 1 -i] = temp;
//        }

        //方式2:(推荐)
        for (int i = 0, j = arr.length - 1 - i; i < j; i++, j--) {
            //交互arr[i] 与 arr[j]位置的元素
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }

//        //方式3:(不建议,一,开辟一个新空间,二,遍历的次数太多)
//        int[] newArray = new int[arr.length];
//        for (int i = arr.length - 1; i >= 0; i--) {
//            newArray[arr.length - 1 - i] = arr[i];
//        }
//        arr = newArray;

        System.out.println();
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t"); //数组在转换之前输出一次,输出结果67	34	76	5	34	7	65	2	3	54	34
        }

    }
}

3. 为什么数组要从0开始编号,而不是1

        数组的索引,表示了数组元素距离首地址的偏离量。因为第1个元素的地址与首地址相同,所以偏移量就是0。所以从0开始。

4. 数组有什么排序的方式,手写一下

        冒泡。

package com.stguigu4.search_sort.exer3;

/**
 * ClassName: BubbleSortTest
 * Package: com.stguigu4.search_sort.exer3
 * Description: 案例:使用冒泡排序,实现整型数组元素的排序操作
 *
 * 比如:int[] arr = new int[]{34,54,3,2,65,7,34,5,76,34,67};
 *
 * @Author 随心油条
 * @Create 2024/1/26 14:30
 * @Version 1.0
 */
public class BubbleSortTest {
    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; i++) {
            System.out.print(arr[i] + "\t");
        }

        //实现冒泡功能
        for (int j = 0; j < arr.length; j++) {
//            for (int i = 0; i < arr.length - 1; i++) {//这样也可以,每一个数都比arr.length次
            for (int i = 0; i < arr.length - 1 - j; i++) {//这种方法每轮可以少j次
                if (arr[i] > arr[i + 1]){
                    //交换arr[i] 和 arr[i + 1]
                    int temp = arr[i];
                    temp = arr[i + 1];
                    arr[i + 1] = arr[i];
                    arr[i] = temp;
                }
            }
        }

        //排序好了之后在进行
        System.out.println();//换行
        //先输出一下原数组
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
    }
}

5. 常见排序算法,说下快排过程,时间复杂度?

        快速排序(Quick Sort)由图灵奖获得者Tony Hoare发明,被列为20世纪十大算法之一,是迄今为止所有内排序算法中速度最快的一种,快速排序的时间复杂度为O(nlog(n))。

        快速排序通常明显比同为O(nlogn)的其他算法更快,因此常被采用,而且快排采用了分治法的思想,所以在很多笔试面试中能经常看到快排的影子。

        排序思想:

  1. 从数列中挑出一个元素,称为"基准"(pivot)
  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
  4. 递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

6. 二分算法实现数组的查找

package com.stguigu4.search_sort.exer2;

/**
 * ClassName: BinarySearchTest
 * Package: com.stguigu4.search_sort.exer2
 * Description: 二分法查找
 *
 * 定义数组:int[] arr2 = new int[]{2,4,5,8,12,15,19,26,37,49,51,66,89,100};
 * 查找元素5是否在上述数组中出现过?如果出现,输出对应的索引值。
 *
 * @Author 随心油条
 * @Create 2024/1/26 11:22
 * @Version 1.0
 */
public class BinarySearchTest {
    public static void main(String[] args) {
        //1.先定义初始化数组
        int[] arr2 = new int[]{2,4,5,8,12,15,19,26,37,49,51,66,89,100};
        int target = 5;
        //定义一个小旗子
        boolean isFlag = false;//判断是否找到了指定元素

        int head = 0;
        int end = arr2.length - 1;
        int middle;
        while (head <= end){
            middle = (head + end)/2;
            if(target == arr2[middle]){
                System.out.println("恭喜你,找到了元素 " + target);
                isFlag = true;
                break;
            } else if (target > arr2[middle]) {
                head = middle + 1;
            }else {//target < arr2[middle]
                end = middle - 1;
            }
        }
        if (!isFlag){
            System.out.println("很遗憾,没有找到元素 " + target);
        }
    }
}

7. 怎么求数组的最大子序列和

/*
 * 输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
 * 求所有子数组的和的最大值。要求时间复杂度为O(n)。
 例如:输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,
 因此输出为该子数组的和18。
 */
public class ArrDemo {
	public static void main(String[] args) {
		int[] arr = new int[]{1, -2, 3, 10, -4, 7, 2, -5};
		int i = getGreatestSum(arr);
		System.out.println(i);
	}
	
	public static int getGreatestSum(int[] arr){
		int greatestSum = 0;
		if(arr == null || arr.length == 0){
			return 0;
		}
		int temp = greatestSum;
		for(int i = 0;i < arr.length;i++){
			temp += arr[i];
			
			if(temp < 0){
				temp = 0;
			}
			
			if(temp > greatestSum){
				greatestSum = temp;
			}
		}
		if(greatestSum == 0){
			greatestSum = arr[0];
			for(int i = 1;i < arr.length;i++){
				if(greatestSum < arr[i]){
					greatestSum = arr[i];
				}
			}
		}
		return greatestSum;
	}
}

  • 19
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值