第四章 数组

1.数组的概念

1.1 概念:

        数组概念:数组就是用于存储数据的长度固定的容器,保证多个数据的数据类型要一致

1.2 定义:

        所谓数组(array),就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,以便统一管理他们,然后用编号区分他们,这个名字称为数组名,编号称为下标或索引(index)。组成数组的各个变量称为数组的元素(element)。数组中元素的个数称为数组的长度(length)。

        

1.3 数组的分类:

1、按照维度分:

  • 一维数组:存储一组数据

  • 二维数组:存储多组数据,相当于二维表,一行代表一组数据,这是这里的二维表每一行长度不要求一样。

2、按照元素类型分:

  • 基本数据类型的元素:存储数据值

  • 引用数据类型的元素:存储对象(本质上存储对象的首地址)(这个在面向对象部分讲解)

注意:无论数组的元素是基本数据类型还是引用数据类型,数组本身都是引用数据类型。

2.一维数组的声明与使用

2.1 一维数组的声明

2.1.1 一维数组的声明/定义格式:
//推荐
元素的数据类型[] 数组名;

//不推荐
元素的数据类型  数组名[];
2.1.2 数组的声明,就是要确定:

(1)数组的维度:在Java中数组的标点符号是[],[]表示一维,[][]表示二维

(2)数组的元素类型:即创建的数组容器可以存储什么数据类型的数据。元素的类型可以是任意的Java的数据类型。例如:int, String等

(3)数组名:就是代表某个数组的标识符,数组名其实也是变量名,按照变量的命名规范来命名。数组名是个引用数据类型的变量,因为它代表一组数据。

        示例:

public class ArrayCase2 {
    public static void main(String[] args) {
        // 数组的声明   两种方式!!!
        int ageArr1[];

        // 推荐使用下面这种!!!
        ⭐int[] ageArr2;  // 存储一组整形的数据

        // 存储一组浮点型数据
        float[] score;

        // 存储一组字符型数据
        char[] hobby;
    }
}

2.2 一维数组初始化格式(有两种)

一、静态初始化(两种):

  • 什么是初始化?

    • 初始化就是确定数组元素的总个数(即数组的长度)和元素的值

  • 什么是静态初始化?

    • 静态初始化就是用静态数据(编译时已知)为数组初始化。此时数组的长度由静态数据的个数决定。

2.2.1 格式一:
数据类型[] 数组名 = {元素1,元素2,元素3...};//必须在一个语句中完成,不能分开两个语句写
2.2.2 格式二:
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3...};
或
数据类型[] 数组名;
数组名 = new 数据类型[]{元素1,元素2,元素3...};
二、动态初始化
2.2.3 格式:
 数组存储的元素的数据类型[] 数组名 = new 数组存储的元素的数据类型[长度];

  或

 数组存储的数据类型[] 数组名;
 数组名字 = new 数组存储的数据类型[长度];
  1. new:关键字,创建数组使用的关键字。因为数组本身是引用数据类型,所以要用new创建数组对象。

  2. [长度]:数组的长度,表示数组容器中可以存储多少个元素。

  3. 注意:数组有定长特性,长度一旦指定,不可更改。和水杯道理相同,买了一个2升的水杯,总容量就是2升是固定的。

        示例:
// 声明数组的方法(存储 5 个整数的数组容器)

// 静态初始化
int[] arr1 = {1, 2, 3, 4, 5};
int[] arr2 = new int[]{1, 2, 3, 4, 5};
int[] arr3;
arr3 = new int[]{1, 2, 3, 4, 5};

// 动态初始化
int[] arr4 = new int[5];
int[] arr5;
arr5 = new int[5];

2.3 一维数组的使用

2.3.1 数组的长度属性:

        数组的长度属性: 每个数组都具有长度,而且是固定的,Java中赋予了数组的一个属性,可以获取到数组的长度,语句为:数组名.length ,属性length的执行结果是数组的长度,int类型结果。

数组名.length
2.3.2 表示数组中的一个元素:

        每一个存储到数组的元素,都会自动的拥有一个编号,从0开始,这个自动编号称为数组索引(index)或下标,可以通过数组的索引/下标访问到数组中的元素。

数组名[索引/下标]
2.3.3 下标范围:

        Java中数组的下标从[0]开始,下标范围是[0, 数组的长度-1],即[0, 数组名.length-1]

示例:
public class ArrayCase3 {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};

        System.out.println("arr数组的长度:" + arr.length);
        System.out.println("arr数组的第1个元素:" + arr[0]);//下标从0开始
        System.out.println("arr数组的第2个元素:" + arr[1]);
        System.out.println("arr数组的第3个元素:" + arr[2]);

        //修改第1个元素的值
        //此处arr[0]相当于一个int类型的变量
        arr[0] = 100;
        System.out.println("arr数组的第1个元素:" + arr[0]);
    }
}
2.3.4 数组下标越界异常:

        当访问数组元素时,下标指定超出 [0, 数组名.length-1] 的范围时,就会报数组下标越界异常:ArrayIndexOutOfBoundsException

2.4 一维数组的遍历

        数组遍历: 就是将数组中的每个元素分别获取出来,就是遍历。遍历也是数组操作中的基石。for循环与数组的遍历是绝配。

示例:
public class ArrayCase5 {
    public static void main(String[] args) {
        int[] int = {1, 2, 3, 4, 5};
        
        // 循环输出数组 int 
        for (int i = 0; i < int.length; i++) {
            System.out.println(int[i]);
        }
    }
}

2.5 数组元素的默认值

        当我们使用动态初始化方式创建数组时,元素只是默认值。

3.一维数组内存解析

3.1 内存概述

        内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁。其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。只要计算机在运行中,CPU就会把需要运算的数据调到内存中进行运算,当运算完成后CPU再将结果传送出来。我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存。

        Java虚拟机要运行程序,必须要对内存进行空间的分配和管理。

3.2 Java虚拟机的内存划分

        为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。

区域名称作用
程序计数器程序计数器是CPU中的寄存器,它包含每一个线程下一条要执行的指令的地址
本地方法栈当程序中调用了native的本地方法时,本地方法执行期间的内存区域
方法区存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
堆内存存储对象(包括数组对象),new来创建的,都存储在堆内存。
虚拟机栈用于存储正在执行的每个Java方法的局部变量表等。局部变量表存放了编译期可知长度的各种基本数据类型、对象引用,方法执行完,自动释放。

3.3 数组下标为什么是0开始

        因为第一个元素距离数组首地址间隔0个单元格。

3.4 两个一维数组内存图

        两个数组独立

public static void main(String[] args) {
    int[] arr = new int[3];
    int[] arr2 = new int[2];
    System.out.println(arr);
    System.out.println(arr2);
}

4.一维数组的常见方法

4.1 数组统计:求总和、均值、统计偶数个数、乘积等

求总和:
public class ArrayCase15 {
    public static void main(String[] args) {        
        int[] arr1 = new int[]{2, 4, 1, 6, 7};

        // 总和及均值
        int sum = arr1[0];
        for (int i = 1; i < arr1.length; i++) {
            sum += arr1[i];
        }
        System.out.println("总和为:" + sum);
        System.out.println("均值为:" + (double) (sum / arr1.length));
    }
}
偶数个数:
public class ArrayCase15 {
    public static void main(String[] args) {        
        // 偶数个数
        int count = 0;
        for (int i = 1; i < arr1.length; i++) {
            if (arr1[i] % 2 == 0) {
                count++;
            }
        }
        System.out.println("偶数个数为:" + count);
    }
}
乘积:
public class ArrayCase15 {
    public static void main(String[] args) {        
        // 总乘积
        int tot = arr1[0];
        for (int i = 1; i < arr1.length; i++) {
            tot *= arr1[i];
        }
        System.out.println("总乘积为:" + tot);
    }
}

4.2 数组找最值

4.2.1 找最大值/最小值
通过记录值:
public class ArrayCase11 {
    public static void main(String[] args) {
        int[] arr1 = new int[]{13, 26, 32, 14, 25};
        int max = arr1[0];
        int min = arr1[0];
        for (int i = 1; i < arr1.length; i++) {
            // 求最大值
            if (max < arr1[i]) {
                max = arr1[i];
            }
            // 求最小值
            if (min > arr1[i]) {
                min = arr1[i];
            }
        }
        System.out.println("最大值是:" + max);
        System.out.println("最大值是:" + min);

    }
}
通过记录下标:
public class ArrayCase11 {
    public static void main(String[] args) {
        int[] arr1 = new int[]{13, 26, 32, 14, 25};
        int maxIndex = 0;
        int minIndex = 0;
        for (int i = 1; i < arr1.length; i++) {
            // 求最大值
            if (arr1[maxIndex] < arr1[i]) {
                maxIndex = i;
            }
            // 求最小值
            if (arr1[minIndex] > arr1[i]) {
                minIndex = i;
            }
        }
        System.out.println("最大值是:" + arr1[maxIndex]);
        System.out.println("最大值是:" + arr1[minIndex]);
    }
}
4.2.2 找最值及其第一次出现的下标
public class ArrayCase13 {
    public static void main(String[] args) {
        int[] arr1 = new int[]{13, 26, 32, 14, 25};
        int maxIndex = 0;
        int minIndex = 0;
        for (int i = 1; i < arr1.length; i++) {
            // 求最大值及下标
            if (arr1[maxIndex] < arr1[i]) {
                arr1[maxIndex] = arr1[i];
                maxIndex = i;
            }
            // 求最小值及下标
            if (arr1[minIndex] > arr1[i]) {
                arr1[minIndex] = arr1[i];
                minIndex = i;
            }
        }
        System.out.println("最大值是:" + arr1[maxIndex] + ",下标为:" + maxIndex);
        System.out.println("最大值是:" + arr1[minIndex] + ",下标为:" + minIndex);
    }
}

4.3 逆序输出

public class ArrayCase14 {
    public static void main(String[] args) {
        int[] arr1 = new int[]{2, 4, 1, 6, 7};
        for (int i = arr1.length - 1; i >= 0; i--) {
            System.out.print(arr1[i]);
        }

        // 逆序
        String outarr = "[";
        for (int i = arr1.length - 1; i >= 0; i--) {
            if (i == arr1.length - 1) {
                outarr += arr1[i];
            } else {
                outarr += "," + arr1[i];
            }
        }
        outarr += "]";
        System.out.println(outarr);

    }
}

4.4 数组的元素查找

4.4.1 顺序查找

顺序查找:挨个查看

要求:对数组元素的顺序没要求

示例代码:
public class ArrayCaseOrderSearch18 {
    public static void main(String[] args) {
        int[] arr = new int[]{2, 4, 1, 6, 7, 9, 3, 8, 5};

        // 索引下标
        Scanner scan = new Scanner(System.in);
        System.out.print("请输入你要查找的数字:");
        int num = scan.nextInt();
        scan.close();
        // 目标值的下标
        int Index = -1;
        for (int i = 0; i < arr.length; i++) {
            if (num == arr[i]) {
                Index = i;
                break;
            }
        }
        if (Index == -1) {
            System.out.println("你输入的不存在!");
        } else {
            System.out.println("你要查找的是:" + num + ",第一次出现的索引下标为:" + Index + ",数组总长度为:" + arr.length);
        }
    }
}
4.4.2 二分查找
public class ArrayCaseDinarySearch19 {
    public static void main(String[] args) {
        // 二分查找(折半查找)
        int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};

        // 输入
        Scanner scan = new Scanner(System.in);
        System.out.print("请输入你要查找的数字:");
        int target = scan.nextInt();
        scan.close();
        // 目标值的下标
        int index = -1;

        // 起始下标位
        int left = 0;
        // 结束下标位
        int right = arr.length - 1;

        while (left <= right) {
            int mid = (left + right) / 2;
            // 判断比较
            if (arr[mid] == target) {
                index = mid;
                break;
            } else if (arr[mid] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        if (index != -1) {
            System.out.println("找到目标值:" + target + ",索引下标为:" + index);
        } else {
            System.out.println("你输入的目标值不存在!");
        }

    }
}

4.5 数组元素排序

4.5.1排序算法概述

        数组的排序算法很多,实现方式各不相同,时间复杂度、空间复杂度、稳定性也各不相同:

  • 时间复杂度:

常见的算法时间复杂度由小到大依次为:Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n2)<Ο(n3)<…<Ο(2n)<Ο(n!)

4.5.2 选择排序
public class SelectOrder20 {
    public static void main(String[] args) {
        // 选择排序(从小到大排)
        // 目标元素设定位置,按照目标的本来元素和目标元素后面的元素进行比较,直到尾部
        // 当比较一轮之后,记录最小值的索引与目标位置进行交换
        int[] arr = {6, 3, 12, 4, 8};
        // 按照循环设定目标位置
        for (int i = 0; i < arr.length; i++) {
            int min = arr[i];
            int index = i;
            // 与目标位后面的元素一一比对
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < min) {
                    min = arr[j];
                    index = j;
                }
            }
            int temp;
            if (index != i) {
                // 中间变量交换
                temp = arr[i];
                arr[i] = arr[index];
                arr[index] = temp;
            }
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}
4.5.3 冒泡排序及优化
public class BubbleOrder21 {
    public static void main(String[] args) {
        // 冒泡排序    两两交换

        // 由小到大排序
        int[] arr = {6, 3, 12, 4, 8};
        int count = 0;
        int tang = 0;
        for (int i = 0; i < arr.length - 1; i++) {
            boolean flag = true;
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j + 1] < arr[j]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    flag = false;
                }
                count++;
            }
            if (flag) {
                break;
            }
            System.out.println("次数:" + count);
            tang++;
        }
        System.out.println("趟数:" + tang);
        System.out.println(Arrays.toString(arr));

    }
}

5.二维数组

        概述:数组中套多个数组

5.1 二维数组的静态初始化(两种格式)

5.1.1 格式一:
int[] arr1 = {1, 2, 3, 4, 5};
5.1.2 格式二:
int[][] secArr2 = new int[][]{{1, 2}, {3, 4}, {5, 6}};
// 格式二的另一种写法
int[][] secArr3;
secArr3 = new int[][]{{1, 2}, {3, 4}, {5, 6}};

5.2 获取二维数组的长度

格式:数组名.length

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

    // 二维数组的长度
    System.out.println(secArr1.length);
}

5.3获取二维数组中的元素

格式:数组名[i][j]

i:代表的是一维数组在二维数组中的索引位置

j:代表的是元素在一维数组中的索引位置

        遍历方法:

1.先遍历二维数组,将每一个一维数组遍历出来

2.再遍历每一个一维数组,将元素获取出来

public static void main(String[] args) {
    // 二维数组  静态初始化
    int[][] secArr1 = {{1, 2}, {3, 4, 5}, {6, 7, 8, 9}};

    // 第一层拿到数组的长度进行遍历
    for (int i = 0; i < secArr1.length; i++) {
        // 然后根据里层数组的长度再次进行遍历
        for (int j = 0; j < secArr1[i].length; j++) {
            System.out.print(secArr1[i][j] + " ");
        }
        System.out.println(" ");
    }
}

5.4 二维数组的动态初始化

1.概述:数组中的套多个数组
2.定义格式
  a.动态初始化
    数据类型[][] 数组名 = new 数据类型[m][n]
    数据类型 数组名[][] = new 数据类型[m][n]
    数据类型[] 数组名[] = new 数据类型[m][n]
    
    m:代表的是二维数组的长度
    n:代表的是二维数组中每一个一维数组的长度

public class SecArrayitra3 {
    public static void main(String[] args) {
        // 二维数组  动态初始化
        int[][] secArr1 = new int[3][2];

        Scanner scan = new Scanner(System.in);
        // 第一层拿到数组的长度进行输入
        for (int i = 0; i < secArr1.length; i++) {
            // 然后根据里层数组的长度再次进行输入
            for (int j = 0; j < secArr1[i].length; j++) {
                System.out.print("请输入第" + i + "行" + "第" + j + "列的数字:");
                secArr1[i][j] = scan.nextInt();
            }
            System.out.println(" ");
        }
        for (int i = 0; i < secArr1.length; i++) {
            for (int j = 0; j < secArr1[i].length; j++) {
                System.out.print(secArr1[i][j] + " ");
            }
            System.out.println(" ");
        }
    }
}

后续内容,正在更新...

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值