【Java】数组

目录

  1.数组的基本概念

1.1什么是数组

1.2数组的创建以及初始化

  1.3   数组的使用

 1.3遍历数组

2.数组是引用数据类型

2.1JVM的内存分布

2.2引用变量

2.3认识null

3.数组的应用

3.1保存数据

3.2作为函数(方法)的参数

3.3做函数的返回值

  4.Arrays的一些方法

4.1 Arrays.toString

4.2 Arrays.sort

4.3 Arrays.fill

4.4 Arrays.equals

4.5Arrays.copyOf   和Arrays.copyOfRange

5.二维数组


  1.数组的基本概念

1.1什么是数组

  数组:可以看成是相同类型元素的一个集合,在内存中是一段连续的空间,比如现实中的车库:

【Java】数组_第1张图片

 车库里有六个车位,并且它们是连续的。在Java中,相当于包含六个相同元素的数组,结合上图我们可以这样来理解数组:

1. 数组中存放的元素其类型相同
2. 数组的空间是连在一起的
3. 每个空间有自己的编号,起始位置的编号为0,即数组的下标

1.2数组的创建以及初始化

  接下来让我们来看看如何在Java中创建一个数组。Java中有三种创建数组的方式。

        //让我们以int[]来举例,其中array1,array2,array3是数组名字
        //前两个数组所表达的意思是一样的,都是int类型的数组,在里面存了1,2,3,4,5这五个数
        //第三个数组规定了数组的大小,由五个int类型的数构成
        int[] array1={1,2,3,4,5};
        int[] array2=new int[]{1,2,3,4,5};
        int[] array3=new int[5];

在第三个数组里,我们看到了数组的大小已经规定好了,但是并没有存入具体的数字。那么它里面会有什么呢?让我们打印这个数组的0下标来看看。

       int[] array3=new int[5];
       System.out.println(array3[0]);

【Java】数组_第2张图片

 可以看到数组里存入的数字是0,那么其它类型的数组默认值是多少呢?让我们来看看下图

【Java】数组_第3张图片

 由此可见,数组在开辟的时候,会自动拥有一个固定的默认值。

  1.3   数组的使用

 数组在内存里是一段连续空间,空间的编号都是从0开始的,依次递增。这个编号称之为数组的下标,我们可以通过数组的下标去访问其任意位置的元素。比如:

int[]array = new int[]{10, 20, 30, 40, 50};
System.out.println(array[0]);
System.out.println(array[1]);
System.out.println(array[2]);
System.out.println(array[3]);
System.out.println(array[4]

【Java】数组_第4张图片

我们还可以通过下标来修改数组中某个元素的值

array[0] = 100;
System.out.println(array[0]);

 【Java】数组_第5张图片

 注意事项:

1.数组是一块连续的内存空间,因此支持随机方位,即通过下标快速访问数组中的任意元素

2.下标从0开始,介于[0,N)不包括N,N为元素个数,使用数组下标访问数组的时候,不能越界,不然会报下标越界异常。

 1.3遍历数组

所谓的“遍历”就是将数组中的所有元素都访问一遍,访问是指对数组中的元素进行某种操作。我们先来看看一种遍历的方法:

int[]array = new int[]{10, 20, 30, 40, 50};
System.out.println(array[0]);
System.out.println(array[1]);
System.out.println(array[2]);
System.out.println(array[3]);
System.out.println(array[4]);

上述代码可以起到对数组中元素遍历的目的,但是有以下几个问题:

1.如果数组中增加了一个元素,就需要增加一条打印语句
2. 如果输入中有100个元素,就需要写100个打印语句
3. 如果现在要把打印修改为给数组中每个元素加1,修改起来非常麻烦

通过观察我们可以发现,每一步的操作都是相同的,所以我们可以使用循环来对数组进行遍历:

int[]array = new int[]{10, 20, 30, 40, 50};
for(int i = 0; i < 5; i++){
System.out.println(array[i]);
}

使用循环以后,问题2和3都得到了解决但是问题1并没有得到解决。我们可以用.length来获取数组的长度,这样,即使增加或者修改数组中的元素,我们也可以把它进行遍历。

in
t[]array = new int[]{10, 20, 30, 40, 50};
for(int i = 0; i < array.length; i++){
System.out.println(array[i]);
}

也可以通过for-each来遍历数组

int[] array={1,2,3};
        for (int x:array){
            System.out.println(x);
        }

2.数组是引用数据类型

  数组不同于基本数据类型,它是一种引用数据类型。为了更好的理解引用数据类型。我们先来谈谈JVM虚拟机中的内存分布。

2.1JVM的内存分布

内存是一段连续的存储空间,主要用来存储程序运行时的数据的。比如

1. 程序运行时代码需要加载到内存
2. 程序运行产生的中间数据要存放在内存
3. 程序中的常量也要保存
4. 有些数据可能需要长时间存储,而有些数据当方法运行结束后就要被销毁
如果对内存的数据不加以区分随意存储,那对于内存的管理来说,会非常的麻烦,所以JVM对内存按照功能不同进行了划分。

【Java】数组_第6张图片

1. 程序计数器 (PC Register): 只是一个很小的空间, 保存下一条执行的指令的地址
2. 虚拟机栈(JVM Stack): 与方法调用相关的一些信息,每个方法在执行时,都会先创建一个栈帧,栈帧中包含有:局部变量表、操作数栈、动态链接、返回地址以及其他的一些信息,保存的都是与方法执行时相关的一些信息。比如:局部变量。当方法运行结束后,栈帧就被销毁了,即栈帧中保存的数据也被销毁了。
3.本地方法栈(Native Method Stack): 本地方法栈与虚拟机栈的作用类似. 只不过保存的内容是Native方法的局部变量. 在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的
4.堆(Heap): JVM所管理的最大内存区域. 使用 new 创建的对象都是在堆上保存 (例如前面的 new int[]{1, 2,3} ),堆是随着程序开始运行时而创建,随着程序的退出而销毁,堆中的数据只要还有在使用,就不会被销毁。
5. 方法区(Method Area): 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据. 方法编译出的的字节码就是保存在这个区域

在引用数据类型里,我们先只关心堆和虚拟机栈这两块空间。

public static void func() {
int a = 10;
int b = 20;
int[] arr = new int[]{1,2,3};
}
//引用数据类型创建的变量,一般称为对象的引用,其空间中存储的是对象所在空间的地址。

【Java】数组_第7张图片

  从这里可以看出,引用变量并没有存储数据本身,可以理解成存储对象在堆空间的起始地址。通过该地址,引用变量可以去操作对象。类似于C语言中的指针,但是Java中引用的操作比指针要简单。

2.2引用变量

我们通过一组代码更好的来理解引用变量

 public static void func() {
            int[] array1 = new int[3];
            array1[0] = 10;
            array1[1] = 20;
            array1[2] = 30;
            int[] array2 = new int[]{1,2,3,4,5};
            array2[0] = 100;
            array2[1] = 200;
            array1 = array2;
            array1[2] = 300;
            array1[3] = 400;
            array2[4] = 500;
            for (int i = 0; i < array2.length; i++) {
                System.out.println(array2[i]);
            }
        }

由以上代码可知,我们创建了两个int类型的数组 array1和array2,分别给它们赋值。当我们把array2赋值给array1的时候。此时我们改变array1中2下标和3下标的值,并且给array2中4下标的赋值。通过遍历数组array2,我们来看看最终的结果。

【Java】数组_第8张图片

可以看到,当我们改变array1数组的值的时候,也改变了array2中的值,这是为什么呢?我们通过画图来分析

【Java】数组_第9张图片

 【Java】数组_第10张图片

 可见,array2赋值给array1的时候,给的是它的地址,而这个地址指向array2在堆中的空间,所以此时这两个数组指向的是同一个空间。

2.3认识null

null在Java中表示“空引用”,也就是不指向对象的引用。有些类似于C语言中的NULL,都表示的是一个无效的内存地址,但C语言中的NULL指向的是0号地址。而Java中的null并没有约定与0号地址有任何关联。

int[] arr = null;
System.out.println(arr[0]);
// 执行结果
Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:6)

3.数组的应用

3.1保存数据

数组可以用来保存数据,如我们想要把1,2,3存到一个数组里可以这样操作:

public static void main(String[] args) {
int[] array = {1, 2, 3};
for(int i = 0; i < array.length; ++i){
System.out.println(array[i] + " ");
}
}

3.2作为函数(方法)的参数

  可以作为参数,与基本数据类型不同的是,基本数据类型在传参的时候并不会影响实参的值,而数组在方法里修改数组里的内容的时候,方法外部的数组内容也会被改变。因为它传递的是数组的地址(引用)。

public static void main(String[] args) {
        int num = 0;
        func(num);
        System.out.println("num = " + num);
    }
    public static void func(int x) {
        x = 10;
        System.out.println("x = " + x);
    } // 执行结果  x = 10  num = 0
//发现在func方法中修改形参 x 的值, 不影响实参的 num 值.



 public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        func(arr);
        System.out.println("arr[0] = " + arr[0]);
    }
    public static void func(int[] a) {
        a[0] = 10;
        System.out.println("a[0] = " + a[0]);
    } // 执行结果 a[0] = 10 arr[0] = 10

//在func方法内部修改数组的内容, 方法外部的数组内容也发生改变.
因为数组是引用类型,按照引用类型来进行传递,是可以修改其中存放的内容的。

3.3做函数的返回值

  数组可以作为函数的返回值来使用,如:把一个数组里的数扩大两倍并以字符串的形式打印出来。

 public static int[] fun(int[] array){
        for (int i = 0; i < array.length ; i++) {
          array[i]=  array[i]*2;
        }return array;
    }
    public static void main(String[] args) {
        int[] array={1,2,3};
        System.out.println(Arrays.toString(fun(array)));
    }
//输出{2,4,6}

  4.Arrays的一些方法

  上述代码我们通过Arrays.toString方法把数组转化成字符串的形式,并且打印。用到了Arrays类的方法。那么Arrays类有哪些方法呢?老cu在这里给大家讲几个常用的方法

4.1 Arrays.toString

  该方法可以数组转化成字符串的形式。在上述代码中我们已经演示过了,所以在这里就不写代码演示了。

4.2 Arrays.sort

对数组指定范围进行排序,排序范围是从元素下标为from,到下标为to-1的元素进行排序。

int[] array = {2,5,0,4,1,-10};
        //对前四位元素进行排序
        Arrays.sort(array, 0, 4);
        for(int i :array)
            System.out.print(i+" ");
        //之前:2 5 0 4 1 -10
         // 结果:0 2 4 5 1 -10 
         

4.3 Arrays.fill

可以为数组填充相同的值

 public static void main(String[] args) {
        int[] array=new int[10];
        Arrays.fill(array,1);
        System.out.println(Arrays.toString(array));
    }// 把数组里的所有数字都填充为1

4.4 Arrays.equals

比较数组里的元素是否相等,如果相等则返回true,否则返回false。

 public static void main(String[] args) {
        int[] array1={1,2,3};
        int[] array2={1,2,3};
        System.out.println(Arrays.equals(array1,array2));
    } //相等返回true

4.5Arrays.copyOf   和Arrays.copyOfRange

拷贝数组里的值给另一个数组

 public static void main(String[] args) {
        int[] array1={0,0,0};
        int[] array2={1,2,3};
        array1=Arrays.copyOf(array2,3);
        System.out.println(Arrays.toString(array1));
    }//输出结果{1,2,3}

截取从第i位开始到第j位 拷贝到另一个数组里

public static void main(String[] args) {
        int[] array1={0,0,0};
        int[] array2={1,2,3};
        array1=Arrays.copyOfRange(array2,2,3);
        System.out.println(Arrays.toString(array1));
    } //输出结果{3}

5.二维数组

  在Java中,关于二维数组。最好的一句诠释就是,二维数组是一种特殊的一维数组。

我们可以这样来理解二维数组。

比如在二维数组  

int[][] array2={{1,2,3,4},{5,6,7,8}};

里面,每行存的其实是每列的地址,地址指向的每列存的是数组的值。

【Java】数组_第11张图片

array2.length的值是2,它获取的是行数(每一行存的是对应的列的地址)。要想遍历这个数组可以用这种方法。

public static void main(String[] args) {
        int[][] array2={{1,2,3,4},{5,6,7,8}};
        //System.out.println(array2.length);
        for (int i = 0; i < array2.length; i++) {
            for (int j = 0; j < array2[i].length; j++) {
                System.out.print(array2[i][j]+" ");
            }
            System.out.println();

        }
    }

【Java】数组_第12张图片

 二维数组还可以不规则,比如

 public static void main(String[] args) {
        int[][] array=new int[2][];
        array[0]=new int[2];
        array[1]=new int[1];
        array[1][0]=3;
        array[0][0]=1;
        array[0][1]=2;
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                System.out.print(array[i][j]+" ");
            }
            System.out.println();

        }
    }

打印出来的结果为

【Java】数组_第13张图片

你可能感兴趣的:(开发语言,java,jvm)