Java 数组零基础入门到精通

这是 JavaMemo 的第 4 篇原创。

image.png 上一节我们彻底搞懂了 Java 中的基础数据类型,本节进一步学习 Java 中的数组。

数组是在几乎所有编程语言都有的数据类型,其本身也是一种数据结构。一说到数组首先就能想到的就是,数组在内存中是一段连续的内存空间,所以我们能通过索引直接访问其中的元素。

这篇文章就把 Java 中数组常用的知识点拿出来一起学习一下,由于面向的是初学者,所以会把一些涉及技术细节的用更适合普通人理解的俗话去演绎,大家搬好小板凳。先来看你一下内容大纲。

Java数组零基础入门--大纲

认识数组

在 Java 中数组是相同类型变量的集合,例如, int 数组就是 int 类型变量的集合。数组中的变量是有序的,每个都有一个索引。

单个变量和数组,数组可以保存多个变量

数组的特点

  • 数组是相同类型的变量的集合,所有元素的类型都一样
  • 可以指定数组包含的元素个数 ,最多为 int 的最大值个元素
  • 每个元素都有一个固定的编号,称之为索引(index ),从0开始递增,索引类型为 int
  • 可以像操作变量一样读写数组中的任何一个元素,如果说之前的变量是一张有名字的纸,可以通过这个名字读写这个变量;数组则是一个有名字的本子。本子有一个名字,每页纸有一个页码。可以通过本子的名字和页码读写对应的数组元素。
  • 数组是定长的创建之后,长度不可以改变。

数组的语法

  • 创建数组的语法:
元素类型[] 变量名 = new 元素类型[数组长度]
复制代码
  • 使用数组的语法:
通过:数组变量名[索引], 
可以使用这个变量,可以读取也可以给它赋值
复制代码

下面看一个例子帮助理解数组的这两个基础语法。

public class CreateArray {
    public static void main(String[] args) {
        int[] intArray = new int[9];

        intArray[2] = 16;

        System.out.println(intArray[2]);

        double[] doubleArray = new double[100];

        System.out.println(doubleArray[66]);
        
        // 也可以在创建数组的时候,指定数组包含的所有元素
        String[] strArray = new String[]{"one", "two"};
        
		System.out.println(strArray[0]);
    }
}
复制代码

例子:用数组处理多门课的成绩

public class ScoreArrayMaxScore {
    public static void main(String[] args) {
        // 声明六个变量, 分别代表六门科目的成绩
        int YuWenIndex = 0;
        int ShuXueIndex = 1;
        int WaiYuIndex = 2;
        int WuLiIndex = 3;
        int HuaXueIndex = 4;
        int ShengWuIndex = 5;

        // 每门课的名字
        String[] names = new String[6];
        names[YuWenIndex] = "语文";
        names[ShuXueIndex] = "数学";
        names[WaiYuIndex] = "外语";
        names[WuLiIndex] = "物理";
        names[HuaXueIndex] = "化学";
        names[ShengWuIndex] = "生物";

        // 每门课的成绩
        double[] scores = new double[6];

        // 用随机数给成绩赋值
        for (int i = 0; i < 6; i++) {
            scores[i] = 80 + Math.random() * 20;
        }

        // 计算最高成绩和最高成绩对应的科目的索引
        double maxScore = -1;
        int maxScoreIndex = -1;
        for (int i = 0; i < 6; i++) {
            System.out.println(names[i] + "的成绩为" + scores[i]);
            if (maxScore < scores[i]) {
                maxScore = scores[i];
                maxScoreIndex = i;
            }
        }

        // 输出最高成绩科目和成绩
        System.out.println("最高分的科目为" + names[maxScoreIndex] + ",成绩为:" + maxScore);

    }
}
复制代码

理解数组

理解计算机如何使用内存,完成变量功能

  • 内存就像是有一沓白纸的本子,只能通过页吗编号访问,也就是所谓的内存地址。
  • 变量就是使用一个固定的地址加上这个地址对应的内存。计算机通过地址,读写地址对应的内存空间完成变量的赋值和访问的功能。就好像可以根据页码编号,在指定的白纸上写字,或者擦掉再复写。
  • 变量的名就是地址,变量的实就是地址指向的内存里的值。

理解数组的名与实

  • 数组的“实〞是一块地址连续的内存,就像是编号连续的一沓白纸。
  • 数组的名,就是这个块连续内存的第一个内存的地址。
  • 数组的变量和基本类型的变量一样,本身代表一个地址。但是与基本变量不一样的是,这个地址的值,是数组的第一个元素所在的内存地址。
  • 通过 **数组变量名[索引] **方式访问数组元素的实质,就是在数组原有地址(第一个元素)的基础上,加上索引,获得想要的元素位于内存的地址后进行访问。

数组的初始值

数组里的每个元素都有初始值,初始值和元素类型有关,是元素类型的默认值,对于数字类型,初始值就是0,对于boolean类型,初始值是 false。

数组的操作

数组的长度

  • 数组变量的length 属性,可以获取数组的长度。
int[] array = new int[10];

// 通过.length获取数组的长度
system.out.println(array.length);
复制代码
  • 数组是定长的,创建之后,长度不可以改变。

数组越界问题

  • 使用数组常见的一个错误是 IndexOutOfBoundException 数组越界,比如下面就是一个越界的例子
public class IndexOutOfBoundExample {
    public static void main(String[] args) {
        int[] array = new int[5];
        System.out.println(array[array.length]);
    }
}
复制代码
  • 如果没有把握数组是否会越界,可以把索引和数组长度做比较,注意索引是从 0 开始的,不是从 1 开始的。
public class CompareIndex {
    public static void main(String[] args) {
        int size = 60;
        double[] array = new double[size];

        for (int i = 0; i < 10; i++) {
            int index = (int) (Math.random() * size * 3);
            if (index >= 0 && index < array.length) {
                System.out.println(array[index]);
            } else {
                System.out.println("数组出界!");
            }
        }
    }
}
复制代码

数组变量指向新数组

  • 数组变量可以指向新的数组实体。这时候,数组变量的值就是新的数组实体的地址了,这种数组变量的赋值操作,叫做让变量指向新的数组。
public class AssignArray {
    public static void main(String[] args) {
        int[] array = new int[3];

        array[0] = 9;

        System.out.println("array长度为" + array.length + "。array[0] = " + array[0] + " array 指向的地址为:" + array);

        array = new int[32];

        System.out.println("array长度为" + array.length + "。array[0] = " + array[0] + " array 指向的地址为:" + array);
    }
}
复制代码

上面的例程的输出是

array长度为3。array[0] = 9 array 指向的地址为:[I@78e03bb5
array长度为32。array[0] = 0 array 指向的地址为:[I@5e8c92f4
复制代码

可以看到数组变量指向新数组后,变量值保存的数组地址发生了变化。

  • 如果没有别的数组变量指向原来的数组实体,也就是说,如果没有数组变量“记得”原来数组的地址,原来的数组实体就再也不可访问,也就好像“消失”了。后面会被GC回收。

多维数组

  • 二维数组是一维数组的延伸。
  • 二维数组定义的语法,比如定义一个doubule类型的二维数组 double[][] = new doube[3][6],第一维有三个元素,每个元素的值都是指向的double一维数组的地址,第二维数组的长度为6。
  • 一般写代码时最多就用到二维数组,再多维,写的程序太难让人理解,不推荐使用
public class MultiDimensionArray {
    public static void main(String[] args) {
        // 创建一个double类型的二维数组
        double[][] multiDimensionArr = new double[3][5];

        // 循环查看每个数组元素的值,在给数组元素赋值前,数组元素的值其实都是每种类型的初始值。
        for (int i = 0; i < multiDimensionArr.length; i++) {
            for (int j = 0; j < multiDimensionArr[i].length; j++) {
                System.out.println("multiDimensionArr[" + i + "][" + j + "]=" + multiDimensionArr[i][j]);
            }
        }

        // 其实第一维的数组,每个元素都是一个下一维度的属于的变量。在这里我们可以改变这个变量的值
        // 也就是让它指向一个新的变量。
        multiDimensionArr[2] = new double[100];

        // 检查每个的数组的长度,发现最后一个的长度不一样了,因为它指向了新的数组。
        for (int i = 0; i < multiDimensionArr.length; i++) {
            System.out.println("multiDimensionArr[" + i + "].length=" + multiDimensionArr[i].length);
        }

    }
}
复制代码

例子-利用二维数组存储多年的成绩

import java.util.Scanner;

public class OneArrayForAll {
    public static void main(String[] args) {

        // 声明六个变量, 分别代表六门科目的成绩
        int YuWenIndex = 0;
        int ShuXueIndex = 1;
        int WaiYuIndex = 2;
        int WuLiIndex = 3;
        int HuaXueIndex = 4;
        int ShengWuIndex = 5;

        // 每门课的名字
        String[] names = new String[6];
        names[YuWenIndex] = "语文";
        names[ShuXueIndex] = "数学";
        names[WaiYuIndex] = "外语";
        names[WuLiIndex] = "物理";
        names[HuaXueIndex] = "化学";
        names[ShengWuIndex] = "生物";

        Scanner scanner = new Scanner(System.in);

        System.out.println("请输入共有多少年的成绩:");

        int yearCount = scanner.nextInt();

        double[][] scores = new double[yearCount][names.length];

        for (int i = 0; i < yearCount; i++) {
            for (int j = 0; j < names.length; j++) {
                scores[i][j] = 80 + Math.random() * 20;
            }
        }

        System.out.println("请问要查看第几年的成绩?");

        int yearToUse = scanner.nextInt() - 1;

        System.out.println("请问要查看第几科的成绩?");

        int scoreToUse = scanner.nextInt() - 1;

        System.out.println("第" + (yearToUse + 1) + "年的第" + (scoreToUse + 1) + "门的成绩是:" + scores[yearToUse][+scoreToUse]);

    }
}
复制代码

总结

关于数组方面的基础内容差不多就是这些,学会后,掌握常规的数组使用方法完全不再话下。

其实真正使用 Java 开发程序的时候大部分时候不会直接使用数组,更多会用 ArrayList 这样支持自动扩容和范型的容器,不过它也是在数组的基础上实现的,学知识跟吃饭一样要一口一口啃,等我们把最基础的知识都掌握了后面会有专门的章节学习 ArrayList 这样的容器。

今天仍然是一篇面向零基础人群的内容,如果你工作中需要开始使用 Java,或者身边有刚开始学 Java 的朋友,欢迎把文章分享给他们。

猜你喜欢

转载自juejin.im/post/7102353340649963528