JavaSE——数组

ced485cbb11e458d81a746890b32cf3f.gif

作者:敲代码の流川枫

博客主页:流川枫的博客

专栏:和我一起学java

语录:Stay hungry stay foolish

工欲善其事必先利其器,给大家介绍一款超牛的斩获大厂offer利器——牛客网

点击免费注册和我一起刷题吧  

目录

1. 数组的定义

2. 数组的创建及初始化

2.1 数组的创建

2.2 数组的初始化

3. 数组的使用

3.1注意事项

3.2数组的遍历

 4. 数组是引用类型

4.1 初始JVM的内存分布

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

4.3 空引用

5. 数组传参


 

1. 数组的定义

数组:是相同类型元素的一个集合

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

2. 数组在内存中是一段连续的空间

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

2. 数组的创建及初始化

2.1 数组的创建

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

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

T[]:数组类型

N:数组长度

int[] array1 = new int[10];

创建了一个数组名是array1,可容纳10个整形元素的整型数组

String[] array2 = new double[3]; 

创建一个数组名array2,可以容纳3个字符串元素的字符型数组 

2.2 数组的初始化

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

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

int[] array1 = new int[10];

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

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

静态初始化虽然没有指定数组的长度,编译器在编译时会根据{}中元素个数来确定数组的长度

静态初始化时, {}中数据类型必须与[]前数据类型一致

静态初始化可以简写,省去后面的new T[]

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

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

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

若没有对数组进行初始化,数组中元素有其默认值

数组中存储元素类型为基类类型,默认值为基类类型对应的默认值

byte,short,int,long类型对应默认值为0

float类型对应默认值为0.0f

double类型对应默认值为0.0

char类型对应默认值为/u0000

boolean类型对应默认值为false

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

3. 数组的使用

3.1注意事项

数组在内存中是一段连续的空间,空间的编号都是从0开始的,依次递增,该编号称为数组的下标,数组可以通过下标访问其任意位置的元素

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

 使用数组一定要下标谨防越界

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

public class Test {
    public static void main(String[] args) {
        int[] array = new int[10];
        System.out.println(array[10]);
    }
}

898b4f98dee44789acea6bebe19c1298.png

3.2数组的遍历

"遍历" 是指将数组中的所有元素都访问一遍, 访问是指对数组中的元素进行某种操作

循环是最常用的遍历方式

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

4af7e68383bf40c897047d4a2354cf10.png

先用循环给array赋值,然后循环遍历数组

注意:在数组中可以通过数组对象.length来获取数组的长度

使用 for-each 遍历数组

for-each 是 for 循环的另外一种使用方式,能够更方便的完成对数组的遍历,可以避免循环条件和更新语句写错

 for (int x:array) {
            System.out.println(x);
        }

e2133e48506a42aea813aa97430b37e0.png

 

 4. 数组是引用类型

4.1 初始JVM的内存分布

 

dcd7c8aa23574c49a68482acbce21e13.png

 方法区:用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译后的代码等数据

方法编译出的的字节码就是保存在这个区域

虚拟机栈:与方法调用相关的一些信息,每个方法在执行时都会创建一个栈帧,栈帧中包含:局部变量表,操作数栈,动态链接,返回地址 和一些其他的信息

方法结束时,栈帧就被销毁了,栈帧中保存的数据也被销毁了

本地方法栈: 本地方法栈与虚拟机栈的作用类似. 只不过保存的内容是Native方法的局部变量. 在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的

堆:JVM所管理的最大内存区域

用new创建的对象都在堆上保存,堆是随着程序的开始运行而创建的,随着程序的退出而销毁

堆中的数据只要还在使用,就不会被销毁

程序计数器:一个很小的空间,保存下一条执行的指令的地址

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

基本数据类型创建的变量,称为基本变量,该变量空间中直接存放的是其所对应的值 

引用数据类型创建的变量,一般称为对象的引用,其空间中存储的是对象所在空间的地址

例如:

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

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

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

array是数组类型的引用变量,其内部保存的内容可以简单理解成是数组在堆空间中的首地址

9263d883fa9943fabcf96bfa5b550057.png

我们可以看出,引用变量并不直接存储对象本身,存储的是对象在堆中空间的起始地址

再看一个例子:

import java.util.Arrays;
public class Test {
    public static void main(String[] args) {

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

        System.out.println(Arrays.toString(array));
        System.out.println(Arrays.toString(array2));
    }
}

939cb9c3ad17467c9dae580a11e3eee6.png

cf39d0bd5ad647d09763ada100289837.png

我们可以看出,一个引用只能指向一个对象,一个对象可以被多个引用指向

当array重新引用别的对象时,JVM会回收掉没有被引用的对象,在C中用malloc开辟出来的空间用完后是需要free的

通过地址,引用变量去操作对象


import java.util.Arrays;
public class Test {
    public static void main(String[] args) {

        int[] array = {1,2,3,4};
        System.out.println(Arrays.toString(array));
        
        int[] array2 = array;
        array2[1] = 10;
        System.out.println(Arrays.toString(array));
        System.out.println(Arrays.toString(array2));
    }
}

c21b75dee913459ab5342e51b2ff3f58.png

 我们可以看出,给array2赋值的同时,array的值也改变了

8e25ac46b945415b8e311c5ed7cd2db1.png

 array2这个引用指向了array这个引用指向的对象,因此给array2赋值的同时,array的值也改变

4.3 空引用

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

public class Test {
    public static void main(String[] args) {
        int[] array = null;
        System.out.println(array[0]);
    }
}

c02643e1ccb14467a27ac3f48360f0df.png

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

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

5. 数组传参

看这块代码:

import java.util.Arrays;
public class Test {
    public static void main(String[] args) {
       int[] array = {1,2,3,4};
       fun1(array);
       //fun2(array);
        System.out.println(Arrays.toString(array));
    }
    public static void fun1(int[] array){
        array = new int[10];
    }
    public static void fun2(int[] array){
        array[0] = 10;
    }
}

8e2366b7f5b84d2c9e55b8ea4018e4bf.png

  我们可以看出,fun1方法中不影响实参的值,并没有利用地址对实参进行操作

340128c97d6644b69aae9987fc468124.png

import java.util.Arrays;
public class Test {
    public static void main(String[] args) {
       int[] array = {1,2,3,4};
       //fun1(array);
       fun2(array);
        System.out.println(Arrays.toString(array));
    }
    public static void fun1(int[] array){
        array = new int[10];
    }
    public static void fun2(int[] array){
        array[0] = 10;
    }
}

61c090fb116b4785958b685fe23c5e62.png

可以看出,这里修改了array的元素

3b603be8998d46208f887eece9b53b90.png

总结: 所谓的 "引用" 本质上只是存了一个地址

Java 将数组设定成引用类型,这样的话后续进行数组参数传参,其实只是将数组的地址传入到函数形参中, 这样可以避免对整个数组的拷贝(数组可能比较长,那么拷贝开销就会很大)

 “ 本期的分享就到这里了, 记得给博主一个三连哈,你的支持是我创作的最大动力!

ced485cbb11e458d81a746890b32cf3f.gif

 

  • 88
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 136
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 136
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YoLo♪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值