当前位置:首页 » 《我的小黑屋》 » 正文

零基础Java第八期:一维数组(1)

12 人参与  2024年11月17日 16:01  分类 : 《我的小黑屋》  评论

点击全文阅读


目录

一、 一维数组的基本概念 

1.1. 什么是数组

1.2. 数组的创建及初始化

1.3. 数组的使用

二、数组是引用类型

2.1. 初始JVM的内存分布

2.2. 基本类型变量与引用类型变量

 2.3. 引用变量的理解

2.4. null 

 三、数组的应用场景

 3.1. 作为函数的参数

3.2. 作为函数的返回值


一、 一维数组的基本概念 

1.1. 什么是数组

       当我们需要存储多个类型相同的变量时,如果一个一个去创建会很麻烦 ,此时我们就可以使用数组去简化这类问题。数组:可以看成是相同类型元素的一个集合。在内存中是一段连续的空间,地址是连续存放的。每个空间有自己的编号,第一个位置的编号为0,即数组的下标。

1.2. 数组的创建及初始化

 (一)数组的创建规则:

数据类型 [] = new 数据类型[N],其中N表示数组的长度。

        int[] array1=new int[10];//表示一个可容纳10个int型的数组        double[] array2=new double[20];//表示一个可容纳20个double型的数组        String[] array3=new String[30];//表示一个可容纳30个String性的数组

 (二)数组的初始化 

数组的初始化主要分为动态初始化以及静态初始化。 

(1)动态初始化:在创建数组时,直接指定数组中元素的个数

int[] array=new int[10]

(2) 静态初始化:在创建数组时不直接指定数据元素个数,而直接将具体的数据内容进行指定

        int[] array4 = new int[]{0,1,2,3,4,5,6,7,8,9};        double[] array5 = new double[]{1.0, 2.0, 3.0, 4.0, 5.0};        String[] array6 = new String[]{"hell", "Java", "!!!"};

       注意:1.静态初始化虽然没有指定数组的长度,编译器在编译时会根据{}中元素个数来确定数组的长度   2.静态初始化时, {}中数据类型必须与[]前数据类型一致   3.静态初始化可以简写,省去后面的new T[]。

       如果没有对数组进行初始化,数组中元素有其默认值。如果数组中存储元素类型为基类类型,默认值为基类类型对应的默认值。 

类型默认值
byte0
short0
int0
long0
float0.0f
double0.0
char/u000
booleanfalse
Stringnull

        在这里我们只演示boolean和String类型的默认值,代码如下,对此代码进行调试,运行最后一行时,我们就可以看到boolean的默认值为false

    public static void main(String[] args) {        boolean[] array=new boolean[3];//默认值为false        System.out.println("=====");        String[] str=new String[3];    }

 

1.3. 数组的使用

(1)数组元素的访问 

      数组是一段连续的内存空间,因此支持随机访问,即通过下标访问快速访问数组中任意位置的元素 ,即我们可以通过下标来进行打印、修改,并且不能越界访问,否则会出现如下报错。

        int[] arrays=new int[]{1,2,3,4};        arrays[2]=10;        System.out.println(arrays[1]);//打印元素        System.out.println(arrays[2]);//修改元素        System.out.println(arrays[4]);//越界访问

(2)遍历数组:将所有元素都访问一遍。

       如果我们一个一个打印,或者对里面的元素进行修改,会非常麻烦。此时我们可以使用for循环来解决。

        int[] arrays = new int[]{1,2,3,4,5,6};        for(int i=0;i<=5;i++){            System.out.println(arrays[i]);        }

     我们来对此代码进行调试,当运行到“System.out.println(arrays[i]);”时,就会产生如下图所示。

       虽然for循环可以帮助我们解决上面提到的问题,但是我们无法获取数组的长度。那我们就可以通过下面的代码来进行实现。

        int[] arrays = new int[]{1,2,3,4};        for(int i=0;i< arrays.length;i++){            System.out.print(arrays[i]);        }        System.out.println();        for (int x:arrays) {            System.out.println(x);        }

      第一种是for循环,原理不必多说;第二种是for-each,原理是遍历数组,将数组中的元素赋值给x,但这种方法无法获取数组元素的下标,也无法对下标进行运算。

     当然还有第三种打印方式,是由Java官方提供操作数组的工具,代码如下:

import java.lang.reflect.Array;import java.util.Arrays;public class Main {    public static void main(String[] args) {        int[] arrays=new int[]{1,2,3,4,5};        String ret=Arrays.toString(arrays);        System.out.println(ret);    }}

         Array需要导入一个Arrays的包,我们可以查看一下toString的源码,是String类型的,所以使用String ret来接收一下,直接打印ret就可以了。 下图为打印结果。

二、数组是引用类型

2.1. 初始JVM的内存分布

       我们经常说数组是引用变量,数组里的元素是如何储存在数组里的呢?要想搞清楚这两个问题,那我们首先需要了解JVM的内存分布。

       我们可以把JVM理解为一个大房子,房子分为客厅、厨房、卧室、厕所。同样,JVM也可以划分出多个内存空间,如下图所示。设想一下,如果我们的房子非常乱,找起东西来就会很麻烦。如果对内存中存储的数据不加区分的随意存储,那对内存管理起来将会非常麻烦。 

2.2. 基本类型变量与引用类型变量

       基本数据类型创建的变量,称为基本变量,该变量空间中直接存放的是其所对应的值;而引用数据类型创建的变量,一般称为对象的引用,其空间中存储的是对象所在空间的地址。 好,我们来看下面一组代码:

public static void main(String[] args){          int a = 1;          int[] arrays = {1,2,3,4,5};

      arrays就是一个局部类型的引用变量,数组里的元素会在堆上有一个地址,arrays这个变量就会在栈上存这个地址;a也是main方法里的局部变量,它只会在栈上开辟内存空间,就不会在堆上。所以引用变量并不直接存储对象本身,可以简单理解成存储的是对象在堆中空间的起始地址。通过该 地址,引用变量便可以去操作对象。

 

 2.3. 引用变量的理解

看下面一组代码:

    public static void main(String[] args) {        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]);        }    }

       array1=array2,相当于我们把array2的地址赋给了array1,则array1就不能存原来的地址,这样就会造成两块引用同时指向一个空间,相当于通过array1去修改并访问array2,所以说打印出来的值则为100、200、300、400、500。那array1之前所指向的内存空间呢?答案是被回收掉了。

2.4. null 

       null 的作用类似于 C 语言中的 NULL (空指针), 都是表示一个无效的内存位置.。因此不能对这个内存进行任何读写操作。 一旦尝试读写, 就会抛出 NullPointerException,说明某个引用为空,访问了一个空的引用。

public class Main {    public static void main(String[] args) {        int[] array1 = {1,2,3};        System.out.println(array1);//打印结果是16进制的地址        int[] array2 = null;//array2属于引用类型,默认值不能为0//      array引用不指向任何对象        System.out.println(array2.length);//null不指向任何对象,运行就会显示空指针异常    }}

     博主还留下了两个问题给你去思考:1、引用可以指向引用吗? 2、一个引用可以指向多个对象吗?好,第一个问题:array1=array2,上面我们提到了,array1指向的是array2所指向的对象。第二个问题:一个引用只能指向一个对象,比如 int a=10,不能说a在栈上存储了10个数据吗。

 三、数组的应用场景

 3.1. 作为函数的参数

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

        虽然两个引用都指向了同一个对象,但两个引用的作用域不一样,上面的array是形参,下面的array是实参 ,打印出来的结果就是1 2 3。在这种情况下,我们修改形参的值, 不影响实参的值。那如果我们来看下面一组代码,参数传数组类型呢?

       两个方法都是传递引用类型,第一个方法改变了形参的地址,形参的指向被改变了;而第二个方法中,形参修改了指向对象的内容。 

public class Main {    public static void func1(int[] array){        array =new int[]{10,20,30,40,50};    }    public static void func2(int[] array){        array[0]=10;    }    public static void main(String[] args) {        int[] array={1,2,3};        func1(array);        print(array);        main1(args);//在main方法中,我们调用main1,就可以同时运行main和main1    }    public static void main1(String[] args) {        int[] array={1,2,3};        func2(array);        print(array);    }

 

3.2. 作为函数的返回值

我们都知道调用方法时,只能返回一个值,那我们可以使用数组来进行多个返回值的接收,代码如下:利用ret来接收,并返回给array。

import java.util.Arrays;public class Main {    public static int[] test(){        int[] ret=new int[2];        ret[0]=10;        ret[1]=20;        return ret;    }    public static void main(String[] args) {        int[] array=test();        System.out.println(Arrays.toString(array));    }}

 


点击全文阅读


本文链接:http://zhangshiyu.com/post/187740.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1