【Java】数组详解

news2024/11/23 15:13:59

文章目录

  • 一、数组的基本认识
    • 1.1 数组的概念
    • 1.2数组的创建与初始化
    • 1.3 数组的使用
  • 二、数组的类型 — 引用类型
    • 2.1 JVM 内存分布
    • 2.2 什么是引用类型
    • 2.3 基本类型变量与引用类型变量的区别
    • 2.4 Java 中的 null
  • 三、数组的应用
    • 3.1 保存数据
    • 3.2 函数参数
    • 3.3 函数返回值


一、数组的基本认识

1.1 数组的概念

数组(Array)是一种用于存储相同类型元素的数据结构。它是一组连续的内存位置,每个位置都存储着一个元素,并通过索引来访问和操作这些元素。数组通常用于存储和处理大量的数据,提供了一种有效的方式来组织和访问数据。

1.2数组的创建与初始化

在 Java 中,数组的创建和初始化可以通过以下几种方式进行:

  1. 静态初始化

在静态初始化中,可以直接指定数组的元素值,并在创建数组时进行初始化。语法格式如下:

dataType[] arrayName = {value1, value2, value3, ...};

示例:

int[] numbers = {1, 2, 3, 4, 5}; // 创建并初始化一个包含5个整型元素的数组
  1. 动态初始化

在动态初始化中,需要先创建数组对象,然后通过索引逐个赋值。语法格式如下:

dataType[] arrayName = new dataType[length];

示例:

int[] numbers = new int[5]; // 创建一个包含5个整型元素的数组
numbers[0] = 1; // 给第一个元素赋值
numbers[1] = 2; // 给第二个元素赋值
// ...
  1. 默认初始化

在默认初始化中,数组的元素会根据其数据类型进行默认初始化。例如,整型数组的元素默认值为0,浮点型数组的元素默认值为0.0,布尔型数组的元素默认值为false,引用类型数组的元素默认值为null。示例:

int[] numbers = new int[5]; // 创建一个包含5个整型元素的数组,默认值为0
  1. 使用 Arrays 类的 fill() 方法

Arrays 类中的 fill() 方法可以用指定的值填充数组的所有元素。语法格式如下:

Arrays.fill(arrayName, value);

示例:

int[] numbers = new int[5];
Arrays.fill(numbers, 0); // 将数组的所有元素设置为0

这些是在 Java 中创建和初始化数组的常用方法。根据需求和场景的不同,选择合适的方法来创建和初始化数组。

1.3 数组的使用

数组中元素访问:

在 Java 中,可以使用索引来访问数组中的元素。数组的索引从0开始,表示数组中元素的位置。通过指定索引值,可以获取特定位置的元素值,对其进行读取、修改或其他操作。

下面是使用索引访问数组元素的示例:

int[] numbers = {1, 2, 3, 4, 5};

// 读取数组中的元素
int firstElement = numbers[0]; // 获取第一个元素,值为1
int thirdElement = numbers[2]; // 获取第三个元素,值为3

// 修改数组中的元素
numbers[1] = 10; // 将第二个元素的值修改为10

System.out.println("First element: " + firstElement); // 输出: First element: 1
System.out.println("Third element: " + thirdElement); // 输出: Third element: 3
System.out.println("Modified array: " + Arrays.toString(numbers)); // 输出: Modified array: [1, 10, 3, 4, 5]

需要注意的是,数组索引必须在有效范围内,即从0到数组长度减1。如果指定了超出范围的索引,会导致数组越界异常(ArrayIndexOutOfBoundsException)。

数组的遍历:

在 Java 中,有多种方式可以遍历数组,对数组中的每个元素进行操作。以下是几种常用的数组遍历方法:

  1. for 循环

使用普通的 for 循环可以遍历数组,通过索引逐个访问数组元素。示例:

int[] numbers = {1, 2, 3, 4, 5};
for (int i = 0; i < numbers.length; i++) {
    int element = numbers[i];
    // 对每个元素进行操作
    System.out.println(element);
}
  1. 增强 for 循环(foreach 循环)

增强 for 循环提供了一种简化的语法,可以直接遍历数组中的元素,无需使用索引。示例:

int[] numbers = {1, 2, 3, 4, 5};
for (int element : numbers) {
    // 对每个元素进行操作
    System.out.println(element);
}
  1. 使用 Arrays 类的 toString() 方法

使用 Arrays 类的 toString() 方法可以将整个数组转换为字符串表示,方便打印或输出。示例:

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

二、数组的类型 — 引用类型

2.1 JVM 内存分布

下面是 JVM 的主要内存分布图:

【说明】

  1. 方法区(Method Area):
    方法区是用于存储类的结构信息(如类的字段、方法、构造函数)、运行时常量池、静态变量、即时编译器编译后的代码等数据。它在JVM启动时被创建,并且是所有线程共享的。在较早的JVM版本中,方法区被实现为永久代(Permanent Generation),但在JDK 8及后续版本中,永久代被元空间(Metaspace)取代。

  2. 虚拟机栈(VM Stack):
    虚拟机栈用于存储线程的方法调用和局部变量信息。每个线程在执行时都会创建一个对应的虚拟机栈,栈中的每个元素被称为栈帧(Stack Frame),用于存储方法的局部变量、操作数栈、动态链接、方法返回值等信息。每个方法在执行时都会创建一个对应的栈帧,并随着方法的进入和退出进行入栈和出栈操作。

  3. 本地方法栈(Native Method Stack):
    本地方法栈类似于虚拟机栈,但是它是为执行本地(非Java)方法服务的。它与虚拟机栈的作用相似,但存储的是本地方法的信息。

  4. 堆(Heap):
    堆是用于存储对象实例的区域。在Java程序运行时,动态分配的对象都存储在堆中。堆是Java虚拟机管理的最大一块内存区域,也是所有线程共享的。堆被划分为新生代(Young Generation)和老年代(Old Generation)等不同的区域,其中新生代又包括Eden空间、Survivor空间等。

  5. 程序计数器(Program Counter):
    程序计数器是用于存储当前线程正在执行的字节码指令的地址或索引。它是线程私有的,每个线程都有自己独立的程序计数器。在任何一个时间点,一个线程都只能执行一个方法的代码,也就是所谓的当前方法。程序计数器用于记录线程执行的位置,以便在发生线程切换时能够恢复到正确的执行位置。

此时,我们要理解引用类型,就只需要理解清楚虚拟机栈和堆这两块内存区域

2.2 什么是引用类型

引用类型(Reference Type)是指在Java中,用于引用对象的类型。与引用类型相对应的是基本类型(Primitive Type),用于直接存储数据的类型,如整数、浮点数、字符等。

引用类型可以是类、接口或数组类型。当我们声明一个引用类型的变量时,实际上在内存中为该变量分配了存储空间,这个存储空间可以用来存储对象的引用(内存地址),而不是实际的对象数据

引用类型的变量本身占用的内存空间是固定的,不受对象大小的影响,因为它只存储了对象的引用。通过这个引用,我们可以间接地访问和操作对象的实例变量和方法

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

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

例如下面的代码:

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

其中,a和b都是基本类型变量,而arr是引用类型变量。但是,它们都是方法内部的变量,因此其存储空间的都被分配在func方法的栈帧中。由于a和b是基本类型变量,它们内部保存的就是给自己初始化的值,即1 0 和 20;而arr是引用类型变量,其内部存储的就是自己所引用数组在堆空间中的首地址。

变量a,b,arr的内存分布可用下图进行简单表示:


从图中可以发现,引用变量并不直接存储对象本身,可以简单理解成存储的是对象在堆中空间的起始地址。通过该地址,引用变量便可以去操作对象。有点类似C语言中的指针,但是Java中引用要比指针的操作更简单。

2.4 Java 中的 null

在Java中,null 是一个特殊的值,表示一个引用类型变量没有引用任何对象。它是一个关键字,可以用来将引用类型变量初始化为一个空值。

当一个引用类型变量被赋值为 null,它表示该变量不引用任何对象,即它不指向任何有效的内存地址。这意味着该变量不能访问该对象的实例变量或调用对象的方法,因为它没有实际的对象引用。

使用 null 有几种常见的情况:

  1. 在声明一个引用类型变量时,如果还没有具体的对象要赋值给它,可以将其初始化为 null
int[] arr = null;
  1. 当需要释放一个对象的引用时,可以将该引用赋值为 null。这样,对象就不再被引用,有助于垃圾回收器判断该对象是否可以被回收。
arr = null;

需要注意以下几点:

  • null 只能被赋值给引用类型变量,不能赋值给基本类型变量,因为基本类型变量不是对象。
  • 当尝试使用一个值为 null 的引用类型变量进行实例变量访问或方法调用时,会导致空指针异常(NullPointerException)。因此,在使用引用类型变量之前,需要进行非空检查,以避免空指针异常的发生。
arr[0] = 1; //空指针异常

使用 null 可以帮助我们处理对象的缺失或无效引用的情况,但需要小心使用,以避免空指针异常。

三、数组的应用

3.1 保存数据

数组经常用于保存一组相关的数据。例如,一个学生成绩表可以使用数组来存储每个学生的成绩,一个商品库存列表可以使用数组来存储每个商品的库存数量。

int[] scores = {85, 90, 78, 92, 88}; // 学生成绩数组
int[] inventory = {10, 5, 20, 15}; // 商品库存数组

3.2 函数参数

数组可以作为函数的参数传递,以便在函数中操作和处理数组数据。例如,一个函数可以接受一个整数数组并计算数组中所有元素的总和。

public static int calculateSum(int[] numbers) {
    int sum = 0;
    for (int i = 0; i < numbers.length; i++) {
        sum += numbers[i];
    }
    return sum;
}

int[] numbers = {1, 2, 3, 4, 5};
int sum = calculateSum(numbers); // 调用函数计算数组元素的总和
System.out.println("数组元素的总和为: " + sum);

3.3 函数返回值

数组也可以作为函数的返回值,用于返回多个相关的值。例如,一个函数可以返回一个包含某个范围内的所有偶数的数组。

public static int[] getEvenNumbers(int start, int end) {
    int size = (end - start) / 2 + 1;
    int[] evenNumbers = new int[size];
    int index = 0;
    
    for (int i = start; i <= end; i++) {
        if (i % 2 == 0) {
            evenNumbers[index] = i;
            index++;
        }
    }
    
    return evenNumbers;
}

int[] evenNumbers = getEvenNumbers(1, 10); // 调用函数获取范围内的所有偶数
System.out.println("范围内的偶数数组: " + Arrays.toString(evenNumbers));

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/630938.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STL——string和vector容器

初识STL **STL的基本概念****vector容器存放内置数据类型****在vector容器中存放自定义数据类型****vector容器嵌套vector容器****string容器——构造函数****string容器——赋值操作****string容器——字符串拼接****string容器——字符串的查找和替换****string容器——字符串…

Java阶段四Day01

Java阶段四Day01 文章目录 Java阶段四Day01Security框架通配符Vue脚手架 Vue-cli关于VUE关于VUE Cli创建Vue Cli工程解决端口被占用 Vue工程的工程结构[.idea]【重要】[node_modules]【重要】[public]favicon.icoindex.html [src][assets][compnents]【重要】[router][store]【…

Kafka详解(一)

第1章 Kafka概述 1.1 定义 1.2 消息队列 目前企业中比较常见的消息队列产品主要有Kafka、ActiveMQ、RabbitMQ、RocketMQ等。Message Queue ② 在大数据场景主要采用Kafka作为消息队列 ② 在JavaEE开发中主要采用ActiveMQ、RabbitMQ、RocketMQ Kafka存储数据&#xff0c;且保证…

虚函数+多态实现原理(一个冷门知识)

目录 多态实现 虚函数定义 先说原理 抛出问题 探究多态底层 冷门知识 多形态的大海 多态实现 完成类多态体现&#xff0c;多态两个条件: 虚函数重写 父类指针或者引用去调用虚函数。 虚函数定义 虚函数重写/覆盖条件 : 函数 三同 (函数名、参数、返回值) 不符合重写&…

【板栗糖GIS】——如何使用插件将微信读书笔记同步到notion

【板栗糖GIS】——如何使用插件将微信读书笔记同步到notion 注&#xff1a;本文创意以及插件开发皆是B站的【三此君】 视频链接如下&#xff1a; 全网唯一支持图文导出的微信读书插件&#xff0c;升级啦&#xff01;主打一个惊艳。_哔哩哔哩_bilibili &#xff0c;我只是记录…

阿里内部人手一份的Spring Cloud Alibaba手册

“微服务架构经验你有吗&#xff1f;” 前段时间一个朋友去面试&#xff0c;阿里面试官一句话问倒了他。实际上&#xff0c;不在 BAT 这样的大厂工作&#xff0c;是很难接触到支撑千亿级流量微服务架构项目的。但也正是这种难得&#xff0c;让各个大厂都抢着要这样的人才&…

linux(信号结尾)

目录&#xff1a; 1.可重入函数 2.volatile关键字 3.SIGCHLD信号 -------------------------------------------------------------------------------------------------------------------------------- 1.可重入函数----------用来描述一个函数的特点的 1.在单进程当中也存…

【数据结构】图的遍历、图的应用

以下是对王道数据结构图的部分选择题的纠错 图的遍历 对于一个非连通无向图G&#xff0c;采用DFS访问所有顶点&#xff0c;在DFSTraverse函数中调用DFS的次数正好等于连通分量个数 一次遍历必然会将一个连通图中的所有顶点都访问到&#xff0c;对于已被访问的顶点不在调用DFS&…

APP测试中ios和Android的区别是什么~

01、常识性区别 02、导航方式 iOS&#xff1a;Tab放在页面底部&#xff0c;不能通过滑动来切换&#xff0c;只能点击。也有放在上面的&#xff0c;也不能滑动&#xff0c;但有些Tab本身可以滑动&#xff0c;比如天猫的。还有新闻类的应用。 Android&#xff1a;一般放在页面…

数据库实验五 函数

任务描述 本关任务&#xff1a;对表达式取整 相关知识 四舍五入的函数 ROUND(X,D) 返回X&#xff0c;其值保留到小数点后D位&#xff0c;而第D位的保留方式为四舍五入。 若D的值为0,则对小数部分四舍五入。 若将D设为负值&#xff0c;保留X值小数点左边的D位 TRUNCATE(X,D)…

《剑指 Offer--LeetCode 学习计划》-- 字符串

剑指 Offer 05. 替换空格&#xff08;Easy&#xff09; 题目描述 请实现一个函数&#xff0c;把字符串 s 中的每个空格替换成"%20"。限制&#xff1a;0 < s 的长度 < 10000。 举例说明 示例 1&#xff1a; 输入&#xff1a;s “We are happy.”。输出&…

K210图像检测(1~8)数字卡片识别

前言 第一次使用该平台。想先找一个简单的识别&#xff0c;来走走流程。就想到了&#xff0c;前几年的送药小车的数字卡片识别。花了半天收集标记图片。在运行时要注意摄像头与数字卡片的高度。不过也有些不足&#xff0c;可能是收集某个数字的训练集的时候&#xff0c;拍摄高度…

文件智能归类,让文件分类变得简单易行

在数字化信息时代&#xff0c;我们经常需要处理各种类型的文件&#xff0c;如文档、图片、视频等&#xff0c;而这些文件可能存在于不同的文件夹、不同的磁盘之间&#xff0c;管理起来十分繁琐。为了解决这个问题&#xff0c;文件智能归类管理应运而生。这种文件管理方式采用智…

公司新招了几个00后,我愿称之为卷王之王

前几天我们公司一下子也来了几个新人&#xff0c;这些年轻人是真能熬啊&#xff0c;本来我们几个老油子都是每天稍微加会班就打算走了&#xff0c;这几个新人一直不走&#xff0c;搞得我们也不好走。 2023年秋招就要开始了&#xff0c;最近内卷严重&#xff0c;各种跳槽裁员&a…

水中声源级SL的求解应用举例

水中声源级SL的求解应用举例 在水声学中&#xff0c;经常会遇到声源级的概念&#xff0c;并根据声源级的大小估计其他重要参数&#xff0c;本文举例说明声源级的概念和定义。 一、声源级的定义 声源级用来描述声音辐射源所产生声信号或噪声在1m距离处的声强量级。其定义为 S …

安卓大作业 书籍列表APP

系列文章 安卓大作业 书籍列表APP 文章目录 系列文章1&#xff0e;背景2&#xff0e;功能3. 源代码获取 1&#xff0e;背景 我做的项目是一个可以查看到书籍列表以及详情效果的内容&#xff0c;主要使用到的技术有Intent数据传递以及数据库存储的应用&#xff0c;其次使用的组…

【笔试强训选择题】Day23.习题(错题)解析

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;笔试强训选择题 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01; 文章目录…

【编译、链接、装载四】汇编知识补充——ATT 汇编语法、寄存器、指令、栈、栈帧

【编译和链接四】编译器后端——生成汇编代码 一、AT&T 汇编语法1、Intel 汇编2、AT&T汇编 二、x86寄存器1、x86通用寄存器2&#xff0e;其他寄存器3、寄存器的具体用途 三、常见的x86指令四、栈和栈帧 一、AT&T 汇编语法 AT&T VS Intel 基于 x86 架构 的处理…

PyCaret初学者指南

&#x1f680;分类 PyCaret的分类模块是一个监督机器学习模块&#xff0c;用于将元素分类到组中。 目标是预测离散和无序的类别标签。一些常见的用例包括预测客户违约&#xff08;是或否&#xff09;、预测客户流失&#xff08;客户将离开或留下&#xff09;、发现疾病&#x…

深入理解深度学习——注意力机制(Attention Mechanism):基础知识

分类目录&#xff1a;《深入理解深度学习》总目录 相关文章&#xff1a; 注意力机制&#xff08;AttentionMechanism&#xff09;&#xff1a;基础知识 注意力机制&#xff08;AttentionMechanism&#xff09;&#xff1a;注意力汇聚与Nadaraya-Watson核回归 注意力机制&#…