数组的定义和使用(全是干货)

简介: 数组的定义和使用(全是干货)

数组的定义和使用

文章目录

1.数组的基本概念

1.1 为什么要用数组

假设我们在要统计5个学生的成绩,并对其打印输出,可能会这样写代码

public class Student {
    public static void main(String[] args) {
        int stu1=90;
        int stu2=93;
        int stu3=85;
        int stu4=87;
        int stu5=80;
        System.out.println(stu1);
        System.out.println(stu2);
        System.out.println(stu3);
        System.out.println(stu4);
        System.out.println(stu5);
    }
}

上述代码是没有一点问题的,但是有不好的就是:当我们需要统计大量同学的成绩时,比如20个、50个、100个……时,总不能连续创建这么多的变量,当所有学生的成绩需要加上5分时总不能一个一个的修改成绩吧,这样的效率简直太低了。通过观察我们发现:所有成绩类型都是int型的,因此我们将这些数据存储到一个容器中,方便统一管理。

容器概念

  • 容器:是将多个数据存储到一起,每个数据称为该容器的元素。
  • 生活中的容器:水杯,衣柜,常见的瓶瓶罐罐……
  • b2eceb0f4693d2a9eff58f3e39222e8e.jpg

1.2什么是数组

数组:相同元素的一个集合。在内存中是一块连续的空间,比如我们常见的停车场:


a07e190719671d65582dfdaf4a6f0764.png

数组好比停车场,车位数好比数组的长度,而汽车就是数组的元素。

因此:

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

1.3数组的创建及初始化

1.3.1数组的创建

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

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

T[]:表示数组的类型

N:表示数组的长度

1.3.2数组的初始化

在Java中数组初始化分两种:

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

int[] array=new int[5];

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

int[] array1=new int[]{1,2,3,4,5,6,7};
double[] array2=new double[]{1.1,2.2,3.3,4.4,5.5};
String[] array3={"hello","java"};//这里省略new String[]编译能通过吗?

静态初始化数组时可以省略new T[],但在编译器编译时还是会还原。

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

int arr[]={1,2,3};//这样初始化可以吗?

Java中数组初始化可以按照C语言中数组初始化的方式,但是这种方法不推荐容易造成数组的类型就是int的误解

  • 如果没有对数组进行初始化,元素中有其默认值
类型 默认值
byte 0
short 0
int 0
long 0
float 0.0f
double 0.0
char /u0000
boolean float
应用类型 null

1.4数组的使用

1.4.1数组元素的访问

数组在内存中是一段连续存在的空间,空间编号都是从0开始,依次递增,编号是数组的下标,数组可以通过下标进行访问数组的元素。数组下标从0开始,介于[0,N)之间不包括N,N为元素个数,不能越界,否则会报错。

int[]array={1,2,3,4,5};
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.4.2遍历数组

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

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

在数组中可以通过 数组名.length 获取数组的长度

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

int[]arr={1,2,3,4,5};
for(int e:arr){
    System.out.println(e);
}

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

2.数组是引用类型

2.1 Java虚拟机(JVM)的内存分布

  1. 内存是一段连续的存储空间,主要用来存储程序运行时数据的。比如:
  2. 程序运行时代码需要加载到内存
  3. 程序运行产生的中间数据要存放在内存
  4. 程序中的常量也要保存
  5. 有些数据可能需要长时间存储,而有些数据当方法运行结束后就要被销毁
    如果对内存中存储的数据不加区分的随意存储,那对内存管理起来将会非常麻烦。

因此JVM也对所使用的内存进行了划分:f23bf5584e7c64aa882492835964b361.png

  • 程序计数器:是一块较小的内存空间,保存下一条执行的指令的地址,它可以看作是当前线程所执行的字节码的行号指示器。
  • 虚拟机栈:Java方法执行的内存模型,每个方法执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法从调用直至完成的过程,都对应着一个栈帧从入栈到出栈的过程。每当一个方法执行完成时,该栈帧就会弹出栈帧的元素作为这个方法的返回值,并且清除这个栈帧,Java栈的栈顶的栈帧就是当前正在执行的活动栈,也就是当前正在执行的方法。
  • 本地虚拟机栈:本地方法栈和虚拟机栈所发挥的作用是很相似的,只不过保存的内容是Native方法的局部变量. 在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的。
  • :JVM所管理的最大内存区域. 几乎所有用new 创建的对象都是在堆上保存 (例如前面的 new int[]{1, 2,3} ),堆是随着程序开始运行时而创建,随着程序的退出而销毁,堆中的数据只要还有在使用,就不会被销毁。
  • 方法区:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据. 方法编译出的的字节码就是保存在这个区域 。

2.2数组在内存中的存储

1.一个数组的内存图

public static void main(String[] args) {
    int[]arr=new int[]{1,2,3};
    System.out.println(arr);//[I@1540e19d
}    

代码执行结果是**[I@1540e19d**,这是数组内容在内存中的地址。new的内容几乎都存储在堆中,方法中的变量arr保存的是数组的地址。

90150d482c237ce04a38c70fab5975da.png

2.两个数组的内存图

2dd627c05c6b62672e415c3f15dcf150.png

3.数组作为函数参数

3.1参数传基本数据类型

数组内容交换:

    public static void swapArray(int[]left,int[]right){
        int[]tmp=left;
        left=right;
        right=tmp;
    }
    public static void method4(){
        int[]array1={1,2,3,4,5};
        int[]array2={10,20,30,40,50};
        swapArray(array1,array2);
        System.out.println(Arrays.toString(array1));
        System.out.println(Arrays.toString(array2));
    }
    public static void main(String[] args) {
        method4();
    }

执行结果:

e4f430335856ada7602e74adb00dceb6.png

数组内容未发生交换。在方法中,如果修改了形参的指向,实参的指向不发生变化。


3cb23c7f3cabb293c93ad230f57156e0.png

3.2参数传数组类型(引用数据类型)
    public static void swap(int[]num,int i,int j){
        int tmp=num[i];
        num[i]=num[j];
        num[j]=tmp;
    }
    public static void method3(){
        int[]array={10,20,30,40};
        swap(array,0,3);
        System.out.println(Arrays.toString(array));
    }
        public static void main(String[] args) {
        method3();
    }

执行结果:

134c95e02419790ce22723c59f967a95.png

内存分布:64db062dca0fe2694909b3e5c3884d52.png

方法的参数为基本类型时,传递的是数据值. 方法的参数为引用类型时,传递的是地址值.

}

public static void main(String[] args) {

method3();

}

执行结果:
[外链图片转存中...(img-u6uthkjy-1660910375540)]
内存分布:
[外链图片转存中...(img-wdluWpRU-1660910375540)]
> **方法的参数为基本类型时,传递的是数据值. 方法的参数为引用类型时,传递的是地址值.**


目录
打赏
0
0
0
0
3
分享
相关文章
智保未来:国泰产险的 AI 网关革新之旅
国泰产险在数智化转型中,全面拥抱大模型技术,通过阿里云云原生API网关简化接入复杂性,提升数据安全性和成本管控能力。公司在外呼、客服、内容生成等业务场景深度应用大模型,解决了多模型统一接入、认证鉴权、内容安全、成本管控和审计风控五大挑战,成为保险行业数智化转型的典范。
208 15
模型上新!来通义灵码体验 QwQ-32B 推理模型!
今天,阿里云发布并开源全新的推理模型通义千问QwQ-32B。通过大规模强化学习,千问QwQ-32B在数学、代码及通用能力上实现质的飞跃,整体性能比肩DeepSeek-R1。在保持强劲性能的同时,千问QwQ-32B还大幅降低了部署使用成本,在消费级显卡上也能实现本地部署。
2264 58
排队算法的matlab仿真,带GUI界面
该程序使用MATLAB 2022A版本实现排队算法的仿真,并带有GUI界面。程序支持单队列单服务台、单队列多服务台和多队列多服务台三种排队方式。核心函数`func_mms2`通过模拟到达时间和服务时间,计算阻塞率和利用率。排队论研究系统中顾客和服务台的交互行为,广泛应用于通信网络、生产调度和服务行业等领域,旨在优化系统性能,减少等待时间,提高资源利用率。
Redis数据结构:List类型全面解析
Redis数据结构——List类型全面解析:存储多个有序的字符串,列表中每个字符串成为元素 Eelement,最多可以存储 2^32-1 个元素。可对列表两端插入(push)和弹出(pop)、获取指定范围的元素列表等,常见命令。 底层数据结构:3.2版本之前,底层采用**压缩链表ZipList**和**双向链表LinkedList**;3.2版本之后,底层数据结构为**快速链表QuickList** 列表是一种比较灵活的数据结构,可以充当栈、队列、阻塞队列,在实际开发中有很多应用场景。
函数计算产品使用问题之如何使用并运行PyTorch
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
112 0
502 Bad Gateway错误分析与解决方案
502 Bad Gateway错误通常发生在客户端与服务器通信时,表示网关或代理未能从上游服务器获取有效响应。本文分析了该错误的可能原因,包括LNMP安装包问题、加速器配置错误、PHP-CGI进程不足等,并提供了详细的解决方案,如手动安装PHP、调整配置参数、清理磁盘空间等。针对Nginx,还介绍了关键参数调整方法和实施步骤。通过这些方法,可有效解决502错误,提高服务器稳定性。注意备份数据并谨慎操作。
1796 2
通义灵码插件:VSCode 的智能编程助手
通义灵码插件:VSCode 的智能编程助手
3438 3
使用Python实现深度学习模型:智能饮食建议与营养分析
使用Python实现深度学习模型:智能饮食建议与营养分析
723 3
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问