day06_数组初识

发布时间:2024年01月21日

数组概述

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

容器概念

  • 容器:是将多个数据存储到一起,每个数据称为该容器的元素。
  • 生活中的容器:水杯,衣柜,教室

百度百科中对数组的定义:

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

数组的特点:

  • 数组的长度一旦确定就不能修改
  • 创建数组时会在内存中开辟一整块连续的空间
  • 存取元素的速度快,因为可以通过[下标],直接定位到任意一个元素、
  • 数组和变量一样,必须先声明并且赋值之后才能使用

一维数组的声明和初始化

数组的声明

实例

       String[] strings; // 推荐
        char chars[];  // 不推荐

一维数组的初始化

格式一:

实例

         /*
        声明int类型的数组,数组名为ages,
        同时初始化,数组中的元素为1, 2, 3, 4, 5
        */
        int[] ages = new int[]{1, 2, 3, 4, 5};

?我们可以先声明数组,之后单独初始化

        double[] scores; //声明double类型的数组,数组名称为scores
        scores = new double[]{1, 2, 3, 4, 5};//数组初始化,数组的元素为1, 2, 3, 4, 5

格式二:

这种格式化,只能声明数组的同时完成初始化,不能分开进行?

实例

        /*
        声明int类型的数组,数组名为arr,
        同时初始化,数组中的元素为1, 2, 3, 4, 5
        */
        int[] arr = {1, 2, 3, 4, 5};

        double[] scores; //声明数组
        // scores = {1, 2, 3, 4, 5}; 错误:必须在一个语句中完成,不能分开两个语句写

?格式三:

实例

       /*
        声明int类型的数组,数组名为array,
        同时,并且初始化。数组元素为默认值
        */
        int[] array = new int[4];

我们可以先声明数组,之后单独初始化

实例

        //声明int类型的数组,数组名为array
        int[] array;
        //数组初始化,数组元素为默认值
        array= new int[4];

数组定义格式详解:

  • 数组存储的元素的数据类型: 创建的数组容器可以存储什么数据类型的数据。
  • 元素的类型可以是任意的Java的数据类型,例如:int, String, Student等
  • [ ] : 表示数组。
  • 数组名字:为定义的数组起个变量名,满足标识符规范,可以使用名字操作数组。
  • new:关键字,创建数组使用的关键字。因为数组本身是引用数据类型,所以要用new创建数组对象。
  • [长度]:数组的长度,表示数组容器中可以存储多少个元素。

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

总结:

  • 定义数组的时候指定具体的元素我们称之为静态初始化。单单指定了具体的长度,而不指定具体的元素称之为动态初始化

数组的默认值

当我们使用动态初始化创建数组的时候,此时只确定了数组的长度,没有明确指明数组中的元素。此时数组中的元素会被赋上默认值。不同的数组类型,默认值也不同,具体如下图所示

一维数组的常见操作

元素的访问

  • 索引: 每一个存储到数组的元素,都会自动的拥有一个编号,从0开始,这个自动编号称为数组索引(index)可以通过数组的索引访问到数组中的元素。
  • 索引范围 :[0, 数组的长度-1]?
  • 格式:数组名[索引]
  • 当访问的下标不存在时 报错 ?ArrayIndexOutOfBoundsException 数组下标越界异常

索引访问数组中的元素:

  • 数组名[索引]=数值,为数组中的元素赋值
  • 变量=数组名[索引],获取出数组中的元素

实例

public class Demo {
    public static void main(String[] args) {
        //定义存储int类型数组,赋值元素1,2,3,4,5
        int[] arr = {1, 2, 3, 4, 5};
        //为0索引元素赋值为6
        arr[0] = 6;
        //获取数组0索引上的元素
        int i = arr[0];
        System.out.println(i);
        //直接输出数组0索引元素
        System.out.println(arr[0]);
    }
}

数组的遍历

数组的长度属性: 每个数组都具有长度,而且是固定的,Java中赋予了数组的一个属性,可以获取到数组的长度,语句为:数组名.length,属性length的执行结果是数组的长度,int类型结果。由次可以推断出,数组的最大索引值为数组名.length-1

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

实例

public class Demo02Test {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 2, 3, 4, 5};
        //打印数组的属性,输出结果是5
        System.out.println("数组的长度:" + arr.length);

        //遍历输出数组中的元素
        System.out.println("数组的元素有:");
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

数组内存图

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

内存详解:

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

数组在内存中的存储

下面代码在内存中的变化,如图所示

public class Demo {
    public static void main(String[] args) {
        int[] arr = new int[3];
        System.out.println(arr);//[I@5f150435
    }

}
数组内存图 ?

小练习

import java.util.Arrays;
// 数组之冒泡排序(Bubble Sort)
public class Demo08Test {
    public static void main(String[] args) {
        //方式一
        int [] arr = {10,20,30,-1111,-2,-10,10220,66};
        for (int i = 0; i < arr.length-1; i++) {
            for (int j = 0; j < arr.length-1-i; j++) {
                if (arr[j] >arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr)); //[-1111, -10, -2, 10, 20, 30, 66, 10220]

        //方式二
        arr =new int[] {10,20,30,-1111,-2,-10,10220,66};
        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] >arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                    flag = false;
                }
            }
            if (flag){
                break;
            }
        }
        System.out.println(Arrays.toString(arr));// [-1111, -10, -2, 10, 20, 30, 66, 10220]
    }
}

二维数组

什么是二维数组?本质上就是元素为一维数组的一个数组。二维数组的长度 指的是 数组内一维数组的个数,n维数组 存储的元素 是 n-1 维数组

int[][] arr; //arr是一个二维数组,可以看成元素是int[]一维数组类型的一个数组

二维数组的声明

格式:

//推荐
元素的数据类型[][] 二维数组的名称;

//不推荐
元素的数据类型  二维数组名[][];
//不推荐
元素的数据类型[]  二维数组名[];

实例

int[] x, y[]; //x是一维数组,y是二维数组
 
数组的静态初始化

如果是静态初始化,右边new 数据类型[][]中不能写数字,因为行数和列数,由{}的元素个数决定

/*
  方式一: 数据类型[][] 标识符 = {{一维数组的元素},{一维数组的的元素},{一维数组的元素}};
	  
*/

int[][] arr = {{10,20},{30,40}};

也可以使用下面这种方式

/*
	  方式二: 数据类型[][] 标识符 = new 数据类型[][]{{一维数组的元素},{一维数组的元素}};
*/

double [][] doubleArr = new double[][]{{3.14,3.45},{6.78,9.78},{10.9}};

数组的动态初始化

确定行数和列数

/*
1.动态初始化方式一:
           数据类型[][] 标识符 = new 数据类型[容量1][容量2];
		      容量1:代表此二维数组内 有多少一维数组
		      容量2:带表一维数组内  有多少个元素
 */
int [][] arr = new int[5][6];

此时创建完数组,行数、列数确定,而且元素也都有默认值,或者我们可以先确定有多少个一维数组,以后在指定每个一维数组中有多少元素

/*
动态初始化方式二:
		 数据类型[][] 标识符 = new 数据类型[容量1][];

             注意事项:使用前 需要给每一个一维数组进行手动指定大小 
*/
	double [][] doubleArr = new double[3][];

常见的二维数组操作

获取二维数组中一维数组的个数

        int [][] arr = new int[5][6];
        //	二维数组名.length
        System.out.println(arr.length); // 5

获取二维数组的某一个一维数组

        int [][] arr = new int[5][6];
        // 二维数组名[行下标] ,行下标的范围:[0, 二维数组名.length-1]
        System.out.println(arr[1]);

获取二维数组的某一个一维数组的元素个数

         int [][] arr = new int[5][6];
        //二维数组名[行下标].length
        System.out.println(arr[0].length);//6

获取二维数组的某一个一维数组的具体元素

         int [][] arr = new int[5][6];
        //二维数组名[行下标][列下标]
        System.out.println(arr[0][0]);//0

二维数组的遍历

public class Demo{
    public static void main(String[] args) {
        String[][] strArr = {{"蔡旭坤", "特朗普"}, {"杨幂", "高圆圆"}, {"胡歌", "彭于晏", "吴彦祖"}};
        //普通for循环 
        for (int i = 0; i < strArr.length; i++) {
            for (int j = 0; j < strArr[i].length; j++) {
                System.out.print(strArr[i][j] + "\t");
            }
            System.out.println();
        }
        System.out.println("=========================");
        //增强for循环
        for (String[] strings : strArr) {
            for (String s : strings) {
                System.out.print(s + "\t");
            }
            System.out.println();
        }
    }
}

数组常见异常

数组越界异常

我们访问数组中不存在的索引,程序运行后,将会抛出 ArrayIndexOutOfBoundsException 数组越界异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码。

    int[] arr = {1,2,3};
    System.out.println(arr[3]);
数组空指针异常

数组的每一行还未分配具体存储元素的空间,此时arr[0]是null,此时访问arr[0][0]会抛出NullPointerException 空指针异常。

        //定义数组
		int[][] arr = new int[3][];
        
        System.out.println(arr[0][0]);//NullPointerException

小练习

/*
输出下面图形
 1
 2 2
 3 3 3
 4 4 4 4
 5 5 5 5 5
 */
public class Demo04Test {
    public static void main(String[] args) {
        int[][] arr = new int[5][];
        for (int i = 0; i < 5; i++) {
            arr[i] = new int[i + 1];
            for (int j = 0; j < arr[i].length; j++) {
                arr[i][j] = i + 1;
            }
        }
        //遍历
        for (int[] ints : arr) {
            for (int i : ints) {
                System.out.print(i + "\t");
            }
            System.out.println();
        }
    }
}

注意事项:

二维数组中存储的是每个一维数组中的地址值

文章来源:https://blog.csdn.net/weixin_44462792/article/details/135675985
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。