导学

数组,这样一个概念,我们在之前的编程学习中也已经学习过了。数组是编程语言中最常用的一种数据类型。可以存储多个数据。数组本质上其实是一堆数的集合。
比如,我们想要保存30个类似的数据,如果不用数组的话,那么就需要设置30个变量来保存。而使用数组,我们只需要设置一个变量就可以了。

数组是相同类型的数据按顺序组成的一种引用数据类型 Java 数组 只能保存相同的数据类型,即指定int数组,该数组就只能保存int类型数据 Java 数组 只能保存规定数量的数据,不能随意的添加,长度一旦确定就不能改变

数组的规范

  • 存放的数据是相同的数据类型
  • 数组的长度在定义时就确定了大小,数组是不可变长度的,或者说叫定长
  • 数组中可以存放任意的数据类型(包含基本数据类型、引用数据类型、数组)
  • 数组本身是引用数据类型(在栈内存中会存储其在堆内存中的引用地址)
  • 数组会在内存中开辟一块连续的内存空间

    一维数组

    数组的定义

    在数组定义的时候,需要和普通变量一样,先指定能储存什么类型的数据

    1. 数据类型[] 变量名; // 强烈建议用这种命名
    2. int[] arr;
    3. 数据类型 变量名[]; // 只要知道就可以,c与c++是这种写法,要区分开来
    4. String arr1[];

    对比之前变量的定义,我们发现,数组与变量的定义不同的地方在于数组的数据类型后面多了一个中括号。

    数组的初始化(创建)

    在 Java 语言中,数组必须先被初始化,才能被使用。所谓的初始化,就是在内存中为数组元素分配空间,并为每个元素赋予初始值。

  • 静态初始化:显式的指定每个数组元素的值,由系统来决定数组的大小。即完全指定数组中保存有什么值,不去指定数组长度,长度由元素的个数来决定;

  • 动态初始化:只需要指定数组的长度,通过程序动态的给每个元素赋值(即由系统为每个数组元素分配初始值)。先指定数组保存元素的个数,再由程序动态的为该数组赋值,【系统会给数组创建初始值(默认值)】

    静态初始化

    语法:
    1. type[] arrayName = {element1, element2,....}; // 比较常见
    2. type[] arrayName = new type[]{element1, element2,...};
    示例:
    注意:数组声明和初始化分开的时候,需要借助new关键字 ```java //方法一: int[] arrs2; arrs2 = new int[]{1, 2 ,3 ,4};

//方法二: int[] arrs = {1, 2, 3, 4}; // 简写,此时该数组长度为4

  1. 该初始化方法,首先定义了数组的内容,同时也根据数组中内容的个数,决定了数组的长度
  2. <a name="e76rc"></a>
  3. #### 动态初始化
  4. 语法:

数据类型[] 数组名= new 数据类型[数组长度];

  1. 示例:

int[] arr = new int[10];//该数组能保存10个元素,即数组长度为10 int[] arr; arr = new int[10];//表示我们创建了一个长度为10的整型数组

  1. 该初始化方法,首先定义了数组的长度,同时根据数据类型的默认值,来暂时确定了数组的内容。
  2. <a name="hP7TF"></a>
  3. #### 数组在内存中的存储与默认值
  4. 非方法级基本数据类型变量(即该变量不写在方法中的时候)存在默认值<br />int byte short long -- 0<br />float double -- 0.0<br />boolean -- false<br />比如`int[] a = new int[5]`a数组是一个整型数组,所以它会取数组的数据类型的默认值为自己的默认值。在此提前和大家说一下,int类型的默认值为0,所以a数组的默认值全部为0。<br />要区分数组使用时和数组定义时的数字意义不同<br />同时数组在内存中会开辟一块连续的内存空间。如下图所示:<br />![](https://cdn.nlark.com/yuque/0/2020/png/1323468/1593572776573-05349a92-ba2b-44bc-bb4a-b3dc0d19e3de.png#align=left&display=inline&height=332&margin=%5Bobject%20Object%5D&originHeight=332&originWidth=398&size=0&status=done&style=none&width=398)
  5. <a name="Um2L6"></a>
  6. ### 数组元素的引用
  7. 语法:

数组名[下标]

  1. > 数组中的索引(下标),通过 arrayName[index] 获取指定位置的数据,index 0 开始,最大值为 length-1
  2. ![](https://cdn.nlark.com/yuque/0/2020/png/1323468/1593572776836-36c914a2-879c-4725-b8ec-ff55c1e4ed3f.png#align=left&display=inline&height=251&margin=%5Bobject%20Object%5D&originHeight=251&originWidth=832&size=0&status=done&style=none&width=832)<br />我们不但可以通过索引来获取数组中元素的值,同时,我们也可以通过索引来改变数组中对应索引的元素的值。<br />示例

int[] arr = new int[10]; System.out.println(arr[0]);//0 arr[0] = 1; System.out.println(arr[0]);//1

  1. <a name="qyt6F"></a>
  2. ### 数组的长度
  3. 语法:

数组名.length

  1. 示例:

int[] a = new int[5]; System.out.println(a.length);//输出5

  1. 我们可以通过`.length`的形式来获取数组的长度。注意,这里的`.`代表着“的”这样一个意思,`length`表示数组的长度属性。<br />我们在之后的课程中会经常用到`.`,在其之后,可以跟着方法名,属性等等。<br />在Java中,"** .** " 操作符后面跟着的标识符如果有小括号就是方法,没有小括号就是属性
  2. 引用数据类型不能直接打印,打印出来的是内存地址+哈希值<br />数组是例外:<br />“[” + 数组数据类型的首字母大写 + @ + 哈希值
  3. <a name="P3wKn"></a>
  4. ### 循环与数组
  5. <a name="95K5s"></a>
  6. #### 普通循环
  7. 我们可以通过循环来为数组进行赋值和取值
  8. - 通过数组索引方式对数组元素进行赋值时,使用数组**.length**属性作为 for 循环的条件。
  9. - 在对数组元素进行操作时,一般使用 for 循环结构。<br />示例:

for (int i = 0; i < arrs3.length; i++) { arrs3[i] = (i+1) * 10; } for (int i = 0; i < arrs3.length; i++) {//注意不要犯数组越界的错误 System.out.println(arrs3[i]); }

  1. <a name="og3w7"></a>
  2. #### 增强型for循环
  3. 增强型for循环又叫foreach循环,foreach循环在数组和之后学习的集合中有着重要的作用

for (数据类型 变量名 : 数组名| 集合名) { element… }

  1. 示例:

for(int a : arrs3) {//循环从arrs3数组中取出元素,并将元素赋值给变量a System.out.println(a); }

  1. > 使用 foreach 一般情况下,只用作**遍历数据**,如果要对数组中元素进行修改,还是需要使用 for 循环带索引的方式进行,因为在上述的代码中,a 只是循环元素的一个副本
  2. > 增强型for循环只能用于遍历元素,不可用于修改元素
  3. <a name="KU0c2"></a>
  4. ### 冒泡排序
  5. 首先我们来看一个问题,如何对一下,ab的值进行交换<br />![](https://cdn.nlark.com/yuque/0/2020/png/1323468/1593572776685-f1466fd3-cb2e-4e05-8be6-951d61c0c1c5.png#align=left&display=inline&height=115&margin=%5Bobject%20Object%5D&originHeight=241&originWidth=566&size=0&status=done&style=none&width=270)<br />那么,如果我们在数组中存放了一组整数,想要对数组中数据进行由大到小的排序。<br />比如这样一组数:<br />![](https://cdn.nlark.com/yuque/0/2020/png/1323468/1593572776534-fae2acdf-b7c2-478e-9742-0debd5f11e0b.png#align=left&display=inline&height=90&margin=%5Bobject%20Object%5D&originHeight=90&originWidth=533&size=0&status=done&style=none&width=533)<br />思路:
  6. 1. 首先对数组中相邻的两个数进行比较,把数组元素从头到尾比较一次以后,我们希望能找出最大的那个值,放到数组的末尾。
  7. 1. 第二次进行比较的时候,找出第二大的值,放到数组的倒数第二位。
  8. 1. 随后进行第三次直到n次比较完成
  9. ![](https://cdn.nlark.com/yuque/0/2020/png/1323468/1593572776922-4cf96485-d6e5-4765-bd55-eed9a844962a.png#align=left&display=inline&height=273&margin=%5Bobject%20Object%5D&originHeight=273&originWidth=527&size=0&status=done&style=none&width=527)<br />![](https://cdn.nlark.com/yuque/0/2020/png/1323468/1593572776574-3c359d83-c11e-4d22-97b1-301f13bf7ce3.png#align=left&display=inline&height=209&margin=%5Bobject%20Object%5D&originHeight=209&originWidth=526&size=0&status=done&style=none&width=526)<br />代码示例:

//冒泡排序法生成从小到大的排序方式 public class MaoPaoDemo { public static void main(String[] args) { int[] mina = { 34, 42, 33, 45, 6, 7 }; System.out.println(“排序前的内容是:”); for (int n : mina) { System.out.print(n + “ “); } int temp; for (int i = 0; i < mina.length - 1; i++) { for (int n = mina.length-1; n > i; n—) { if (mina[n] < mina[n - 1]) { temp = mina[n - 1]; mina[n - 1] = mina[n]; mina[n] = temp; } } } System.out.println( ‘\n’+ “排序后的内容是:”); for (int j : mina) { System.out.print(j+” “); } } }

  1. <a name="01i7B"></a>
  2. ## 二维数组
  3. 在之前的课程中,我们也提到数组中可以放置基本数据类型和引用数据类型,尤其是数组中也可以放置数组。<br />数组中包含数组
  4. <a name="hVWc1"></a>
  5. ### 二维数组的声明与创建
  6. 语法:

三种形式: 数据类型[][] 数组名 数据类型 数组名[][] 数据类型[] 数组名[]

  1. 示例:

int[][] arr; int arr[][]; int[] arr[];

  1. <a name="djXk4"></a>
  2. ### 二维数组的初始化与引用
  3. 在学习二维数组的时候,我们需要知道二维数组存放的是什么样的数据;<br />如图:<br />![](https://cdn.nlark.com/yuque/0/2020/png/1323468/1593572776666-46a58db1-c127-46cc-a68d-1663e3b0e8c7.png#align=left&display=inline&height=146&margin=%5Bobject%20Object%5D&originHeight=146&originWidth=690&size=0&status=done&style=none&width=690)
  4. ```java
  5. //二维数组静态初始化
  6. int[][] arr = { //二维数组即数组包含数组
  7. {85,89,90},
  8. {75,65,85},
  9. {80,84,95}
  10. }
  11. //定义与初始化分开
  12. int[][] arr1;
  13. arr1 = new int[][]{ {..}, {..}, {..} };
  14. //静态初始化数组的引用,同样借助于索引
  15. System.out.println(arr.length);//二维数组长度,指二维数组内部包含了几个一维数组
  16. System.out.println(arr[1].length);
  17. //通过二维数组索引的形式,将得到二维数组中保存的对应的数组,并通过.length的形式得到保存的数组的长度
  18. System.out.println(arr[1][0]);//此处借助的是索引加索引的形式
  19. for(int i=0;i<arr.length;i++){
  20. System.out.println("保存的第"+(i+1)+"个数组中有元素为:");
  21. for(int t=0;t<arr[i].length;t++){
  22. System.out.println(arr[i][t]);
  23. }
  24. }

想要保存该类数据,就需要使用二维数组了。
所以,我们可以将二维数组看做一个几行几列的表格这样一个形式。
如果我们想要表示上述表格中的数据,就可以采用如下的方式
语法:

  1. 数据类型[][] 数组名;//先声明一个数组
  2. 数组名 = new 数据类型[长度][长度];//对数组进行初始化
  3. 数据类型[][] 数组名 = new 数据类型[长度][长度];//对数组声明的同时进行初始化

示例:

  1. //二维数组的动态初始化
  2. int[][] arr = new int[3][3];
  3. //创建了一个三行三列的数组,其实指的是二维数组中会保存三个一维数组,每个一维数组都只能保存3个元素
  4. System.out.println(arr[2][1]);//第三行第二列的数据
  5. arr[1][2] = 9;
  6. //想要每个小数组保存的数据个数不一样,可以在进行动态初始化的时候只指定行数
  7. int[][] arr1 = new int[2][];
  8. //System.out.println(arr1[0][0]);
  9. //会发生空指针异常,原因在于从某个引用数据类型的数据中获取数据,但是该引用数据类型不存在
  10. //动态的指定二维数组的列数
  11. arr1[0] = new int[3];//第一行指定有三列

5. Java数组 - 图1

  1. //想要输出第三行第二列的数据:
  2. System.out.println(arr[2][1]);
  3. //为第二行第三列的数据赋值为9:
  4. arr[1][2] = 9;
  5. // 创建float类型的数组,只指定行数
  6. // 注意:只指定行数的写法是可行的,但只指定列数和全不指定的写法是错误的
  7. float arr1 = new float[3][];
  8. // 因为没有指定列数,对该数组取值会出现空指针错误
  9. //System.out.println(arr1[0][0]);
  10. // 针对于该二维数组进行创建行
  11. arr1[0] = new float[3];//第一行有三列,这样的写法可以指定每行有着不同的列
  12. arr1[1] = new float[2];//第二行有二列
  13. arr1[2] = new float[1];//第三行有一列
  14. System.out.println(arr1[0][0]);//0.0
  15. System.out.println(arr1[0][3]);//数组下标越界

以上使用的属于动态的初始化创建,接下来我们来看看静态的初始化创建。

语法:

  1. 数据类型[][] 数组名 = {{x,,x,x},{x,x},{x,x,x,x},...,{x}};

示例:

  1. int[][] arr = {{1,2,3},{1,2,3},{1,2,3}};//三行三列的数组
  2. int[][] arr = {{1},{1,2},{1,2,3}};//三行不同列的数组

引用:

  1. System.out.println(arr[0][1]);//arr数组第一行第二列的元素
  2. System.out.println(arr.length);//arr数组的长度
  3. System.out.println(arr[0].length);//arr数组第一行的长度
  4. //循环输出二维数组的内容
  5. for(int i = 0; i < arr.length; i++) {
  6. for(int t = 0; t < arr[i].length; t++) {
  7. System.out.println(arr[i][t]);
  8. }
  9. }