【Java.SE】数组的定义与使用

这篇具有很好参考价值的文章主要介绍了【Java.SE】数组的定义与使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

作者简介: 辭七七,目前大一,正在学习C/C++,Java,Python等
作者主页: 七七的个人主页
文章收录专栏:Java.SE,本专栏主要讲解运算符,程序逻辑控制,方法的使用,数组的使用,类和对象,继承和多态,抽象类和接口等内容
欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖

【Java.SE】数组的定义与使用


1. 数组的基本概念

1.1 什么是数组

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

【Java.SE】数组的定义与使用

在java中,包含6个整形类型元素的数组,就相当于上图中连在一起的6个车位,从上图中可以看到:

  1. 数组中存放的元素其类型相同

  2. 数组的空间是连在一起的

  3. 每个空间有自己的编号,其实位置的编号为0,即数组的下标。

1.2 数组的创建及初始化

1.2.1 数组的创建

T[] 数组名 = new T[N];

T:表示数组中存放元素的类型

T[]:表示数组的类型

N:表示数组的长度

int[] array1 = new int[10];       // 创建一个可以容纳10个int类型元素的数组

double[] array2 = new double[5];  // 创建一个可以容纳5个double类型元素的数组

String[] array3 = new double[3];  // 创建一个可以容纳3个字符串元素的数组

数组的定义:

public class TestDemo {
    public static void main(String[] args) {
        int[] array = {1,2,3,4};
    }
}

画图理解:
【Java.SE】数组的定义与使用

1.2.2 数组的初始化

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

  1. 动态初始化:在创建数组时,直接指定数组中元素的个数
int[] array = new int[10];
  1. 静态初始化:在创建数组时不直接指定数据元素个数,而直接将具体的数据内容进行指定
    语法格式:T[] 数组名称 = {data1, data2, data3, ..., datan};
int[] array1 = new int[]{0,1,2,3,4,5,6,7,8,9};

double[] array2 = new double[]{1.0, 2.0, 3.0, 4.0, 5.0};

String[] array3 = new String[]{"hell", "Java", "!!!"};

【注意事项】

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

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

double[] array2 = {1.0, 2.0, 3.0, 4.0, 5.0};

String[] array3 = {"hell", "Java", "!!!"};

打印结果:
【Java.SE】数组的定义与使用
这说明数组里存储的是地址。(可以理解成地址,但是不是真实的地址,是哈希值)

  • 数组也可以按照如下C语言个数创建,不推荐
/*

该种定义方式不太友好,容易造成数组的类型就是int的误解

[]如果在类型之后,就表示数组类型,因此int[]结合在一块写意思更清晰

*/

int arr[] = {1, 2, 3};
  • 静态和动态初始化也可以分为两步,但是省略格式不可以。
int[] array1;

array1 = new int[10];
 

int[] array2;

array2 = new int[]{10, 20, 30};
 

// 注意省略格式不可以拆分, 否则编译失败

// int[] array3;
// array3 = {1, 2, 3};
  • 如果没有对数组进行初始化,数组中元素有其默认值
    1. 如果数组中存储元素类型为基类类型,默认值为基类类型对应的默认值,比如:
      【Java.SE】数组的定义与使用

    2. 如果数组中存储元素类型为引用类型,默认值为null

1.3 数组的使用

1.3.1 数组中元素访问

数组在内存中是一段连续的空间,空间的编号都是从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]);
 

// 也可以通过[]对数组中的元素进行修改

array[0] = 100;

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

【注意事项】

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

  2. 下标从0开始,介于[0, N)之间不包含N,N为元素个数,不能越界,否则会报出下标越界异常。

int[] array = {1, 2, 3};

System.out.println(array[3]);  // 数组中只有3个元素,下标一次为:0 1 2,array[3]下标越界

 

// 执行结果

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 100

        at Test.main(Test.java:4)

抛出了 java.lang.ArrayIndexOutOfBoundsException 异常. 使用数组一定要下标谨防越界.
【异常】

  1. 算数异常
  2. 数组越界异常

1.3.2 遍历数组

所谓 “遍历” 是指将数组中的所有元素都访问一遍, 访问是指对数组中的元素进行某种操作, 比如:打印。

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 来获取数组的长度

int[]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);
}

for-each 是 for 循环的另外一种使用方式. 能够更方便的完成对数组的遍历. 可以避免循环条件和更新语句写错.
【for-each循环和for循环的区别】
for-each循环拿不到下标

2. 数组是引用类型

2.1 初始JVM的内存分布

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

  1. 程序运行时代码需要加载到内存

  2. 程序运行产生的中间数据要存放在内存

  3. 程序中的常量也要保存

  4. 有些数据可能需要长时间存储,而有些数据当方法运行结束后就要被销毁

如果对内存中存储的数据不加区分的随意存储,那对内存管理起来将会非常麻烦。
因此JVM也对所使用的内存按照功能的不同进行了划分:
【Java.SE】数组的定义与使用
平时所说的栈就是Java虚拟机栈,局部变量存放在栈里

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

2.2 基本类型变量与引用类型变量的区别

基本数据类型创建的变量,称为基本变量,该变量空间中直接存放的是其所对应的值;
而引用数据类型创建的变量,一般称为对象的引用,其空间中存储的是对象所在空间的地址

public static void func() {
    int a = 10;
    int b = 20;
    int[] array = new int[]{1,2,3};
}

在上述代码中,a、b、arr,都是函数内部的变量,因此其空间都在main方法对应的栈帧中分配。

a、b是内置类型的变量,因此其空间中保存的就是给该变量初始化的值。

array是数组类型的引用变量,其内部保存的内容可以简单理解成是数组在堆空间中的首地址。
【Java.SE】数组的定义与使用
从上图可以看到,引用变量并不直接存储对象本身,可以简单理解成存储的是对象在堆中空间的起始地址。通过该地址,引用变量便可以去操作对象。有点类似C语言中的指针,但是Java中引用要比指针的操作更简单。

图中是array这个引用指向了数组对象

2.3 再谈引用变量

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

在栈上的存储布局图如下:
【Java.SE】数组的定义与使用

当前这个数组对象 有两个引用在指向
两个引用同时指向了一个对象

所以,当array[0] = 99
array2[0] = ?答案是99

问:引用可以指向引用吗?
答案是:不可以
引用要指向另一个引用所指向的对象
如:array2这个引用指向了array这个引用所指向的对象

public static void func() {
    int[] array1 = new int[3];
    array1[0] = 10;
    array1[1] = 20;
    array1[2] = 30;
    //执行完之后array1里放了三个变量,分别是10,20,30
 
    int[] array2 = new int[]{1,2,3,4,5};
    array2[0] = 100;
    array2[1] = 200;
    //执行完之后array2里放了五个变量,分别是100,200,3,4,5
 
    array1 = array2;
    array1[2] = 300;
    array1[3] = 400;
    array2[4] = 500;
    //这个代码首先是把array2里面的值赋给了array1,
    //此时array1里面的值变成了100,200,3,4,5
    //然后又对array1里面下标为2,3,4的值进行修改,
    //执行完之后array1里面的值变成了100,200,300,400,500
    for (int i = 0; i < array2.length; i++) {
       System.out.println(array2[i]);
   }
}

对第三段代码的画图理解:
【Java.SE】数组的定义与使用

当func方法执行完毕之后,此时array1,array2是局部变量,会被回收

【Java.SE】数组的定义与使用
【Java.SE】数组的定义与使用

2.4 认识 null

null 在 Java 中表示 “空引用” , 也就是一个不指向对象的引用.

int[] arr = null;

System.out.println(arr[0]);
 

// 执行结果

Exception in thread "main" java.lang.NullPointerException

 at Test.main(Test.java:6)

null 的作用类似于 C 语言中的 NULL (空指针),都是表示一个无效的内存位置,因此不能对这个内存进行任何读写操作。一旦尝试读写,就会抛出 NullPointerException。
NullPointerException为空指针异常,空指针异常会伴随整个学习的过程,如果以后空指针异常,那么要定位,看哪个指针是空的

注意: Java 中并没有约定 null 和 0 号地址的内存有任何关联

3. 数组的应用场景

3.1 保存数据

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 class TestDemo {
    public static void func1(int[] array) {
        array = new int[10];
    }

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

调用func1部分的理解(调用func1会给array1分配一块内存)画图理解:
【Java.SE】数组的定义与使用
定义一个新的数组给array之后
【Java.SE】数组的定义与使用
影响了形参的指向,但是并不会影响实参的指向,所以打印结果为1,2,3,4


调用func2部分的理解(调用func2会给array2分配一块内存)画图理解:
【Java.SE】数组的定义与使用
在这种情况下可以通过修改形参的变量来改变实参

1. 参数传基本数据类型

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 值。
2. 参数传数组类型(引用数据类型)

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方法内部修改数组的内容,方法外部的数组内容也发生改变。
因为数组是引用类型,按照引用类型来进行传递,是可以修改其中存放的内容的。
总结: 所谓的“引用”本质上只是存了一个地址。Java 将数组设定成引用类型,这样的话后续进行数组参数传参,其实只是将数组的地址传入到函数形参中。这样可以避免对整个数组的拷贝(数组可能比较长,那么拷贝开销就会很大)。

3.3 作为函数的返回值

数组可以直接作为函数值返回,看如下代码:

public class TestDemo {
    public static int[] func3() {
        int[] array = {1, 2, 3, 4,5,6};
        return array;
    }

    public static void main(String[] args) {
        int[] ret = func3();
        for (int i = 0; i < ret.length; i++) {
            System.out.print(ret[i]+" ");
        }
    }
}

打印结果:
【Java.SE】数组的定义与使用

画图理解:
【Java.SE】数组的定义与使用
当func3走完之后,array在堆上的空间就会被回收掉,但是他所指向的对象依然存在,所以说对象一定在队上,引用变量不一定在栈上

比如:获取斐波那契数列的前N项

public class TestArray {
    public static int[]b(int n){
        if(n <= 0){
            return null;
       }
 
        int[] array = new int[n];
        array[0] = array[1] = 1;
        for(int i = 2; i < n; ++i){
            array[i] = array[i-1] + array[i-2];
       }
 
        return array;
   }
 
    public static void main(String[] args) {
        int[] array =b(10);
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
       }
   }
}

关于【Java基础篇】方法的使用(方法的重载和递归),七七就先分享到这里了,如果你认为这篇文章对你有帮助,请给七七点个赞吧,如果发现什么问题,欢迎评论区留言!!💕💕文章来源地址https://www.toymoban.com/news/detail-496497.html

到了这里,关于【Java.SE】数组的定义与使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java 字符串数组定义_「string数组」string 数组怎么定义

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站 点击跳转浏览。 String arr[] = new String[10]; //创建一个长度为10的String 类型数组。 String arr[] = {“张三”,“李四”}; 这个是最常用的 String[] arr = new String[10];

    2024年02月15日
    浏览(51)
  • Java之数组的定义

    目录 1. 数组的基本概念 1.1 为什么要使用数组 1.2 什么是数组 1.3 数组的创建及初始化 1.3.1 数组的创建 1.3.2 数组的初始化 1.4 数组的使用 1.4.1 数组中元素访问 1.4.2 遍历数组 2. 数组是引用类型 2.1 初始JVM的内存分布 2.2 基本类型变量与引用类型变量的区别 2.3 再谈引用变量 2.4

    2024年02月03日
    浏览(31)
  • Java 基础入门篇(三)—— 数组的定义与内存分配

    数组就是一个容器,用于在程序中存储一批同种类型的数据。 使用场景:一旦确定了数据的具体值,我们就用这种方式存储批量数据。 使用场景:适合做一开始不能确定具体数据的情况。先定义数组,后赋值数据进去。 动态初始化数组的元素存在默认值: 注: 数据类型[

    2024年02月02日
    浏览(46)
  • 【javaSE】 数组的定义与使用

    目录 数组的基本概念 为什么要使用数组 什么是数组 数组的创建及初始化 数组的创建 数组的初始化 动态初始化 静态初始化  注意事项 数组的使用 数组中元素访问 注意事项 遍历数组 数组是引用类型 初识JVM的内存分布 基本类型变量与引用类型变量的区别 再谈引用变量 ​

    2024年02月15日
    浏览(41)
  • JAVASE---数组的定义与使用

    数组是具有相同类型元素的集合,在内存中连续存储。 1. 数组中存放的元素其类型相同 2. 数组的空间是连在一起的 3. 每个空间有自己的编号,起始位置的编号为0,即数组的下标 数组的创建 T代表每个元素的类型 N代表元素的个数/数组长度 数组的初始化 数组的初始化主要分

    2024年02月11日
    浏览(35)
  • 【JAVASE】学习数组的定义与使用

    ✅作者简介:大家好,我是橘橙黄又青,一个想要与大家共同进步的男人😉😉 🍎个人主页: 再无B~U~G-CSDN博客 目标: 1. 理解数组基本概念 2. 掌握数组的基本用法 3. 数组与方法互操作 4. 熟练掌握数组相关的常见问题和代码 数组:可以看成是 相同类型元素的一个集合 。

    2024年04月15日
    浏览(33)
  • C语言自定义数据类型(二)使用结构体数组

    一个结构体变量中可以存放一组有关联的数据(如一个学生的学号、姓名、成绩等数据)。如果有 10 个学生的数据需要参加运算,显然应该用数组,这就是结构体数组。结构体数组与以前介绍过的数值型数组的不同之处在于每个数组元素都是一个结构体类型的数据,它们都分别

    2024年01月19日
    浏览(49)
  • JavaSE进阶 | 二维数组的定义和使用、查找和排序算法

    目录 🥅二维数组 ❤️二维数组的遍历 ❤️动态初始化二维数组 🥅数组知识点总结 🥅习题练习 ❤️用数组模拟栈 ❤️模拟酒店的订房退房功能 ❤️杨辉三角 ❤️把数据存入数组,保证值各不相同 ❤️数组元素的赋值与数组复制 ❤️数组元素的反转 ❤️数组的扩容与缩

    2024年02月14日
    浏览(41)
  • JAVA的sort用法详解(二维数组排序,List<>排序,lambada表达式,自定义类型排序)

    目录 前言: 一维数组降序: 方法1.Comparator接口: 代码实现: 方法2.Collections.reverseOrder(): 代码实现:  二维数组排序: 代码如下: List排序: 代码如下: 自定义类型比较排序: 按照年龄逆序排序: 按照姓名升序排序: lambada表达式简写: 一维数组逆序代码: 二维数组排

    2024年04月09日
    浏览(65)
  • springboot yml文件自定义配置的读取、使用 字符串 数组 对象 集合

    .yml 配置 controller代码 实体类 Student.java Users.java User.java 方式一、 http://localhost:9801/test/test1 方式二、 http://localhost:9801/test/test2 方式三、 http://localhost:9801/test/test3 参考: SpringBoot:yml文件详解-CSDN博客 https://www.jb51.net/article/216769.htm

    2024年02月05日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包