java学习笔记4

发布于:2025-03-19 ⋅ 阅读:(17) ⋅ 点赞:(0)

数组的概述

一维数组 

声明

初始化

数组元素的引用

数组元素的默认初始化值

public class OneArrayTest {
    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};

//        String[] foods;
//        foods = new String[]{"拌海蜇", "龙须菜", "炝冬笋", "酱茄子"};

//        String[] foods;
//        foods = new String[4];

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

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

        //错误的方式
        //int[] arr2 = new int[3]{1,2,3}; // 动静结合
        //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]);
        }
        for (int i = 0; i < prices.length; i++) {
            System.out.println(prices[i]);
        }
    }
}

 

一维数组的使用

一维数组的内存解析

package com.atguigu1.one;

/**
 * ClassName: OneArrayTest1
 * Package: com.atguigu1.one
 * Description:
 *
 * @Author: shkstart
 * @Create 2025-03-17 15:38
 * @Version: 1.0
 */
public class OneArrayTest1 {
    public static void main(String[] args) {
        //5.数组元素的默认初始化值
        int[] arr1 = new int[3]; //动态初始化
        System.out.println(arr1[0]);//0
        short[] arr2 = new short[4];
        for (int i = 0; i < arr2.length; i++) {
            System.out.println(arr2[i]);
        }
        //浮点型数组元素的默认值初始化值:0.0
        double[] arr3 = new double[5];
        System.out.println(arr3[0]);
        // 字符型数组元素的默认初始化值:0(或理解为'\u0000')
        char arr4[] = new char[4];
        System.out.println(arr4[0]);

        if(arr4[0] == 0){
            System.out.println("1111"); //1111
        }
        if(arr4[0] == '0'){
            System.out.println("2222"); //不输出,字符型初始化值不为'0'
        }
        if(arr4[0] == '\u0000'){
            System.out.println("3333");//3333
        }
        //>boolean型数组元素的默认初始化值:false
        boolean[] arr5 = new boolean[5];
        System.out.println(arr5[0]);

        //>引用数据类型数组元素的默认初始化值: null
        String[] arr6 = new String[5];
        for(int i = 0 ; i < arr6.length ; i++){
            System.out.println(arr6[i]);
        }
        if(arr6[0] == null){
            System.out.println("aaa"); //aaa
        }
        if(arr6[0] == "null"){
            System.out.println("bbb"); //不输出
        }
        //6.数组的内存解析

    }
}

练习题:

多维数组

多维数组的使用

package com.atguigu2.two;

/**
 * ClassName: TwoArrayTest
 * Package: com.atguigu2.two
 * Description:
 *
 * @Author: shkstart
 * @Create 2025-03-17 17:56
 * @Version: 1.0
 */
public class TwoArrayTest {
    public static void main(String[] args) {
        //1.数组的声明与初始化
        //复习
        int[] arr1 = new int[]{1,2,3};
        //1.方式1:静态初始化:数组变量的赋值和数组元素的赋值分开进行
        int[][] arr2 = new int[][]{{1,2,3},{4,5},{6,7,8,9}};
        //方式2:动态初始化1:数组变量的赋值和数组元素的赋值分开进行
        String[][] arr3 = new String[3][4];
        //方式2:动态初始化2
        double[][] arr4 = new double[2][];
        //其他正确写法
        int arr5[][] = new int[][]{{1,2,3},{4,5},{6,7,8,9}};
        int[] arr6[] = new int[][]{{1,2,3},{4,5},{6,7,8,9}};
        int arr7[][] = {{1,2,3},{4,5},{6,7,8,9}};
        String arr8[][] = new String[3][4];

        //错误的写法:
        //int[][] arr9 = new int[3][4]{{1,2,3},{4,5,6},{7,8,9}};
        //int[3][4] arr10 = new int[][]{{1,2,3},{4,5,6},{7,8,9}};
        //int[][] arr11 = new int[][10];
        //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 double[4];
        arr4[0][1] = 1.0;
        System.out.println(arr4[0][1]); //1.0
        //3.数组的长度
        System.out.println(arr2.length); //3
        System.out.println(arr2[0].length); //3
        System.out.println(arr2[1].length); //2
        System.out.println(arr2[2].length); //4
        //4.如何遍历数组
        for (int i = 0; i < arr2.length; i++) {
            for (int j = 0; j < arr2[i].length; j++) {
                System.out.print(arr2[i][j] + " ");
            }
        }
    }
}

二维数组的内存解析

public class TwoArrayTest1 {
    public static void main(String[] args) {
        //5.数组元素的默认初始化值
        //以动态初始化方式1说明:
        int[][] arr1 = new int[3][2];
        //外层元素默认值:
        System.out.println(arr1[0]); //地址值 [I@4eec7777
        System.out.println(arr1[1]); //地址值  [I@3b07d329
        //内层元素默认值
        System.out.println(arr1[0][0]); //0

        boolean[][] arr2 = new boolean[3][4];
        //外层元素默认值:
        System.out.println(arr2[0]);//地址值
        //内层元素默认值
        System.out.println(arr2[0][0]); //false

        String[][] arr3 = new String[4][2];
        //外层元素默认值:
        System.out.println(arr3[0]);//地址值 [Ljava.lang.String;@404b9385
        //内层元素默认值
        System.out.println(arr3[0][0]); //null

        //****************************
        //以动态初始化方式2说明:
        int[][] arr4 = new int[4][];
        //外层元素默认值:
        System.out.println(arr4[0]);//null
        //内层元素默认值:
        System.out.println(arr4[0][0]);//报错 NullPointerException

//        String[][] arr5 = new String[5][];
//        //外层元素默认值:
//        System.out.println(arr5[0]);//null
//        //内层元素默认值:
//        System.out.println(arr5[0][0]);//报错 NullPointerException
        //6.数组的内存解析
    }
}

数组中涉及到的常见算法

题目练习:

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

声明:int[] x,y[];在给x,y变量赋值以后,以下选项允许通过编译的是:
6;d)
a)   x[0]= y;           no
b)   y[0]= x            yes
c)   y[0][0] = x;       no
d)   x[0][0]= y;        no
e)   y[0][0]= x[0];     yes
f)   x = y;             no
提示:
一维数组:int[] x 或者int x[]
二维数组:int[][] y或者 int[] y[] 或者 int y[][]
public class ArrayExer02 {
    public static void main(String[] args) {
        // = : 赋值符号
        int i = 10;
        int j = i;
        long l = i; // 自动类型提升
        byte b = (byte) i; // 强制类型转换

        //举例:数组
        int[] arr1 = new int[10];
        byte[] arr2 = new byte[20];
        //arr1 = arr2; //编译不通过,原因:int[],byte[] 是两种不同类型的引用变量
        System.out.println(arr1);
        System.out.println(arr2);
        int[][] arr3 = new int[3][2];
//        arr3 = arr1; //编译不通过
        arr3[0] = arr1; //数组类型和维数一致才可以赋值
        System.out.println(arr3[0]); //[I@4eec7777
        System.out.println(arr1); //[I@4eec7777
    }
}

杨辉三角 

案例:使用二维数组打印一个 10 行杨辉三角。
提示:
1.第一行有 1 个元素,第 n 行有 n 个元素
2.每一行的第一个元素和最后一个元素都是 1
3.从第三行开始,对于非第一个元素和最后一个元素的元素。即:
yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];
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];
            //3.给数组的元素赋值
            //3.1给数组每行的首末元素赋值为1
            yanghui[i][0] = yanghui[i][i] = 1;
            //3.2给数组每行的非首末元素赋值
            //if(i>=2){ //这个判断可以去掉
                for(int j=1;j<yanghui[i].length-1;j++){ //j从每行的第2个元素开始,到倒数第2个元素结束
                    yanghui[i][j] = yanghui[i-1][j] + yanghui[i-1][j-1];
                }
            //}
        }
        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();
        }
    }
}

数组的复制 

public class ArrayExer04_1 {
    public static void main(String[] args) {
//        (1)创建一个名为ArrayTest的类,在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");
        }
//        (4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。
        //array2 = array1;  //array2与array1指向了同一个地址值,修改其中的任何一个,这两个变量的值都会改变
        array2 = new int[array1.length];
        for (int i = 0; i < array1.length; i++) {
            array2[i] = array1[i];
        }
        for (int i = 0; i < array2.length; i++) {
            if(i%2==0){
                array2[i] = 2*i;
            }
        }
        System.out.println(array2);
//        (5)打印出array1.
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + "\t");
        }
    }
}

数组的反转

案例:
定义数组:int[] arr =new int[]{34,54,3,2,65,7,34,5,76,34,67};
如何实现数组元素的反转存储?你有几种方法。
public class ArrayExer05 {
    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");
        }
        System.out.println();
        //反转操作
        //方式1:
        //for (int i = 0; i < arr.length; i++) { //前一半与后一半反转,只需要执行数组的一般即可,前一半反转之后,后一半继续反转,返回的结果值就是原来的值
//        for (int i = 0; i < arr.length/2; i++) {
//            //交互arr[arr.length - 1 - i]与arr[i]位置的元素
//            int 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<j;i++,j--){
            //交换arr[i]与arr[j]位置的元素
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
        //方式3:不推荐
//        int[] newArr = new int[arr.length];
//        for(int i = arr.length - 1; i>=0; i--) {
//            newArr[arr.length - 1 -i] = arr[i];
//        }
//        for(int i = 0;i<newArr.length;i++) {
//            System.out.print(newArr[i] + "\t");
//        }
//        System.out.println();
        //遍历
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
    }
}

数组的扩容

案例1:数组的扩容:
现有数组 int[] arr=new int[]{1,2,3,4,5};
现将数组长度扩容1倍,并将10,20,30三个数据添加到arr数组中,如何操作?
public class ArrayExer01_1 {
    public static void main(String[] args) {
        int[] arr = new int[]{1,2,3,4,5};

        //扩容1倍的空间
//        int[] newArr = new int[arr.length *2];
        //或
        int[] newArr = new int[arr.length << 1];

        //将原来的数组中的元素复制到新的数组中
        for (int i = 0; i < arr.length; i++) {
            newArr[i] = arr[i];
        }
        //将10,20,30三个数据添加到新的数组中
        newArr[arr.length] = 10;
        newArr[arr.length + 1] = 20;
        newArr[arr.length + 2] = 30;

        //将新的数组的地址赋值给原有的数组变量
        arr = newArr;
        //遍历arr
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+"\t"); //1	2	3	4	5	10	20	30	0	0
        }
    }
}

数组的缩容 

案例:数组的缩容:
现有数组 int[] arr={1,2,3,4,5,6,7}。现需删除数组中索引为4的元素
public class ArrayExer01_2 {
    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 4, 5, 6, 7};
        int deleteIndex = 4;
        //方式1:不新建数组
//        for (int i = deleteIndex; i < arr.length-1; i++) {
//            arr[i] = arr[i+1];
//        }
        //修改后元素,设置为默认值
        //arr[arr.length - 1] = 0;
        //方式2:新建数组,新的数组的长度比原来数组的长度少1个
        int[] newArr = new int[arr.length-1];
        for(int i = 0; i < deleteIndex; i++){
            newArr[i] = arr[i];
        }
        //新数组比原有的数组长度少1  i < arr.length-1
        for(int i = deleteIndex; i < arr.length-1;i++){
            newArr[i] = arr[i+1];
        }
        arr = newArr;
        //遍历arr数组
        for(int i = 0; i<arr.length; i++){
            System.out.print(arr[i]+"\t"); //1	2	3	4	6	7
        }
    }
}

线性查找,二分法查找

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

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 = true;
//        for (int i = 0; i < arr1.length; i++) {
//            if(arr1[i] == target){
//                System.out.println("找到了"+target+",对应的位置为"+i); //找到了5,对应的位置为7
//                isFlag = false;
//                break;
//            }
//        }
        //通过isFlag可以来判断没有找到的提示
//        if(isFlag){
//            System.out.println("不好意思,没有找到此元素");
//        }
        //方式2
        int i = 0;
        for (; i < arr1.length; i++) {
            if(arr1[i] == target){
                System.out.println("找到了"+target+",对应的位置为"+i); //找到了5,对应的位置为7
                isFlag = false;
                break;
            }
        }
        //通过判断i是否等于数组长度,可以来判断,是通过找到了数组当中的元素,通过break退出的循环,还是没有找到元素,通过for循环遍历完了来退出的循环
        if(i == arr1.length){
            System.out.println("不好意思,没有找到此元素");
        }
    }
}
案例2:二分法查找,数组必须有序
定义数组:int[] arr2 = new int[]{2,4,5,8,12,15,19,26,37,49,51,66,89,100};
查找元素5是否在上述数组中出现过?如果出现,输出对应的索引值。
public class BinarySearchTest {
    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 = 17;
        int head = 0; //默认的首索引
        int end = arr2.length - 1; //默认的尾索引
        boolean isFlag = false; //判断是否找到了指定元素
        while(head <=end){
            int middle = (head + end)/2;
            if(target == arr2[middle]){
                System.out.println("找到了" + target + ",对应位置为" + middle);
                isFlag = true;
                break;
            }else if(target > arr2[middle]){
                head = middle + 1;
            }else{
                end = middle - 1;
            }
        }
        if(!isFlag){
            System.out.println("不好意思,未找到元素");
        }
    }
}

总结: 

排序算法

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");
        }
        System.out.println();
        //冒泡排序,实现数据元素从小到大排序
        for (int j = 0; j < arr.length-1; j++) {
            for(int i = 0; i<arr.length-1-j;i++){
                if(arr[i] > arr[i+1]){
                    //交换arr[i]和arr[i+1]
                    int temp = arr[i];
                    arr[i] = arr[i+1];
                    arr[i + 1] = temp;
                }
            }
        }
        System.out.println();
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
    }
}

定义了一个基准值pivot,有两个指针,一个从数组的从前往后指,另外一个从后往前指,从前往后走,找到的第一个low比pivot大的,就停下来,high从后往前走,找到第一个比pivot小的就停下来,交换low与high,按照当前的索引,继续执行上述操作

第一轮操作:跟n的复杂度是同阶的,时间复杂度为O(n)

第二轮操作同理

排序算法性能对比 

各种内部排序方法性能比较

排序算法的选择

Arrays工具类的使用

 

数组工具类Arrays的使用(熟悉)
1.Arrays类所在位置:处在java.util包下
2.作用:
java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索)的各种方法。
public class ArrayTest {
    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};
        System.out.println(arr1 == arr2); //false
        boolean isEquals = Arrays.equals(arr1,arr2);
        System.out.println(isEquals); //true
        //2.String toString(int[] a):输出数组元素信息。
        System.out.println(arr1); //[I@4eec7777
        System.out.println(Arrays.toString(arr1)); //[1, 2, 3, 4, 5]
        //3.void fill([] 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):二分查找
        // 使用前提:当前数组必须是有序的
        int index = Arrays.binarySearch(arr3,15);
        if(index >= 0){
            System.out.println("找到了,索引位置为:" + index);
        }else{
            System.out.println("未找到");
        }
        System.out.println(index); //-5,未找到
    }
}

数组使用中的常见异常

1.数组的使用中常见的异常小结
数组角标越界的异常:ArrayIndex0ut0fBoundsException
空指针的异常:NullPointerException


2.出现异常会怎样?如何处理?
> 一旦程序出现了异常,代码就会终止执行
> 针对于异常提供的信息,修改对应代码,避免异常再次出现
public class ArrayExceptionTest {
    public static void main(String[] args) {
        //1.数组角标越界的异常:
        int[] arr = new int[10];
        //角标的有效范围:0,1,2,3,...,9
//        System.out.println(arr[10]);
//        System.out.println(arr[-1]);
        // 2.空指针异常:
        //情况1:
//        int[] arr1 = new int[10];
//        arr1 = null;
//        System.out.println(arr1[0]); //0

        //情况2:
//        int[][] arr2 = new int[3][];
//        arr2[0] = new int[10]; // 此行代码不存在时,下一行代码出现NullPointerException
//        System.out.println(arr2[0][1]);  //NullPointerException
        //情况3:
//        String[] arr3 = new String[4];
//        System.out.println(arr3[0].toString()); //NullPointerException
    }
}