Java中的数组
前言:
本篇博客将为大家介绍Java中的数组的相关知识。
目录
基本介绍
概念相关
数组的使用
数组是引用类型
应用场景
保存数据
作为方法的参数
作为方法的返回值
练习
数组转字符串
数组拷贝
求数组中元素的平均值
查找数组中的指定元素(二分查找+顺序查找)
数组排序(冒泡排序)
数组逆序
二维数组
基本介绍
概念相关
数组可以看成是相同类型元素的集合。在内存中是一段连续的空间,每个空间都有自己的编号,编号从0开始。
数组的使用
- 创建数组:T[] 数组名 = new T[N];
- T表示数组中存放的元素的数据类型
- T[]表示数组的类型
- N表示数组的长度
- 数组的初始化(一共有三种形式):
- 动态初始化:在创建数组时,直接指定数组元素的个数
- int[] arr = new int[10];
- 静态初始化:在创建数组的时候,不直接指定数组元素个数,而是对元素的具体内容进行指定
- int[] arr = new int[]{12,23,43,21,43};
- int[] arr = {12,23,43,21,43};(对上面的写法再次进行简化)
- 注意:
- 静态初始化虽然没有指定数组的长度,但是编译器会按照其存放的元素的个数来确定其长度
- 静态初始化中的后面的new T[]虽然可以省略,但在编译的时候还是会还原的
- 数组也可以按照C语言中数组的创建方式来创建,但是不推荐。T[]写在一起更加清晰明了,让人立刻就明白T[]是数组的类型
- 静态初始化和动态初始化都可以写成两步,但是省略后面new T[]的静态静态初始化方法不可以

- 如果没有对数组初始话,里面存放的是默认值。基本数据类型存基本数据类型的默认值;引用类型存引用类型的默认值。
- 基本数据类型的默认值:
- 动态初始化:在创建数组时,直接指定数组元素的个数
- 数组的使用:
- 数组中元素的访问:数组在内存中是一段连续空间,空间的编号都是从0开始,依次递增,该编号称为数组的下标,数组可以通过其下标访问数组中的任意元素(即,支持随机访问)。其编号是从)开始的,假设数组中共有N个元素,那么编号,也就是下标的大小只能在[0,N)这个范围,大于等于N都会导致数组越界(java.lang.ArrayIndexOutOfBoundsException)。

- 遍历数组:所谓遍历,就是把数组中的元素全部访问一遍;访问是指对数组中的元素进行某种操作,这里以打印为例。像数组中的元素的访问的例子那样,arr6中的所有元素都可以通过一个一个地打印出来,从而达到遍历的效果。但是我们不禁思考:如果一个数组有很多元素呢(比如100个),我们也要这样一个一个地去敲每一步的打印吗?这么做的工作量显然十分巨大。仔细思考,我们会发现我们可以通过循环很容易实现遍历,从而减少代码量:
- 我们可以通过for-each循环来遍历:

- 就通过for循环来实现:(当然,其他循环也是可以的,这里也可以只是举例)
- 这时,另外一个疑问又来了:我们要如何去获取数组的长度呢?此处我们自己举例写的arr6数组,且可以看到它的长度(起码我们可以自己数一下),但是总是有一些场景我们是不能确定其长度或者长度在改变的,那么我们要如何获取数组的长度呢?我们可以通过”数组对象.length“来获取其长度

- 这时,另外一个疑问又来了:我们要如何去获取数组的长度呢?此处我们自己举例写的arr6数组,且可以看到它的长度(起码我们可以自己数一下),但是总是有一些场景我们是不能确定其长度或者长度在改变的,那么我们要如何获取数组的长度呢?我们可以通过”数组对象.length“来获取其长度
- 我们可以通过for-each循环来遍历:
- 数组中元素的访问:数组在内存中是一段连续空间,空间的编号都是从0开始,依次递增,该编号称为数组的下标,数组可以通过其下标访问数组中的任意元素(即,支持随机访问)。其编号是从)开始的,假设数组中共有N个元素,那么编号,也就是下标的大小只能在[0,N)这个范围,大于等于N都会导致数组越界(java.lang.ArrayIndexOutOfBoundsException)。
数组是引用类型
首先,我们先基本了解一下JVM:

程序计数器(PC Register):一块很小的空间,保存下一条执行指令的地址。
虚拟机栈(JVM Stack):与方法调用的一些相关信息,每个方法在执行的时候,都会先创建一个栈帧,栈帧中包含有:局部变量表、操作数栈,动态链接,返回地址以及一些其他的信息,保存的都是一些和方法执行时的相关信息。如:局部变量。方法在运行完以后,栈帧就会被销毁,即保存在栈帧中的数据也会被销毁。
本地方法栈(Native Method Stack):本地方法栈和虚拟机栈相似,只不过保存的是Native方法的局部变量。有些版本的JVM(如HotSpot)实现中本地方法栈和虚拟机栈是一起的。
堆(Head):JVM所管理的最大内存区域,使用new创建的对象都是在堆上保存的。堆是随着程序开始运行时而创建的,随着程序的退出而销毁,堆中的数据只要还有在使用的,就不会被销毁。
方法区(Method Area):用于存储已经被虚拟机加载的类信息,常量、静态变量、即时编译器编译后的代码等数据。方法编译出的字节码就是保存在这个区域的。
接下来,我们将主要涉及两个部分:堆和虚拟机。
基本数据类型创建的变量,称为基本变量,该变量空间存放的就是其保存的值;
而引用数据类型创建的变量,一般称为对象的引用,其空间存放的对象的地址。
举例:
注意:
- 对于这种写法(如下图),我们不能说一个引用指向了一个引用(这句话是错的,引用不能指向引用),我们应该说,一个引用指向了另一个引用所指向的对象

图解:
- 在Java中,null表示空引用,也就是不指向任何对象的引用

- Java中并没有约定null和0有任何关系。
应用场景
保存数据

作为方法的参数

图解:
作为方法的返回值

把func3方法中返回的arr的地址给了ret,使得ret指向了ret这个引用指向的地址(func3中的代码也可以直接简化成return new int[]{1,2,3};)
注意:对象一定是在堆上的,引用变量不一定是在栈上的。
练习
数组转字符串

记得要导包:import java.util.Arrays;(java.util.Arrays包里面包含了一些操作数组的常用方法)
我们也可以自己尝试实现一下这个方法:
public class Demo3 { public static String myToString(int[] arr){String ret ="[";for (int i = 0; i < arr.length; i++) {ret += arr[i];if(i != arr.length -1){ret += ",";}}ret += "]";return ret;}public static void main(String[] args) {int[] arr = {1,2,3};System.out.println(myToString(arr));}
}
数组拷贝
单纯的拷贝:
这里要注意,不能直接int[] copy = arr; 这样不是拷贝,是让copy拿到了arr里面放的地址,从而指向了它指向的引用,并没有创建新的数组,不是拷贝。
法二:
直接利用Arrays自带的拷贝方法(copyOf(原数组,新数组长度)):
值得注意的是:copyOf方法有很多方法和它构成重载,我们只需要在选择满足自己需求的那个即可。
copyOf方法还可以改变新的数组的长度:
拷贝一定范围的数据:
copyOfRang(原数组,初始拷贝下标,结束拷贝下标):


如果拷贝的范围超出了原来数组的长度,就只能能拷贝多少拷贝多少,那些没拷贝到的就还是初始值0。 
System.arraycopy(原数组,原数组开始被拷贝的下标,新数组,新数组开始拷贝的下标,拷贝的长度);

注意:方法中的最后一个数是从原数组中拷贝过来的数据的长度要格外小心是否越界,要注意在起始拷贝下标的基础上新数组是否能接收这么长的数据,原数组是否能给出这么多的数据供拷贝。
求数组中元素的平均值
import java.util.Arrays;
public class Demo3 {
public static double avg(int[] arr){int sum = 0;for (int i = 0; i < arr.length; i++) {sum += arr[i];}return sum/(double)arr.length;//注意类型转换}public static void main(String[] args) {int[] arr = {1,2,3,4,5,6,7,8,21};System.out.println(avg(arr));}
}

查找数组中的指定元素(二分查找+顺序查找)
顺序查找:
import java.util.Arrays;
public class Demo3 {//顺序查找:public static int findVal(int[] arr, int i){for (int j = 0; j < arr.length; j++) {if(arr[j] == i){return j;}}return -1;//数组下标不可能是负数,返回负数说明没有找到}public static void main(String[] args) {int[] arr = {1,2,3,4};int ret = findVal(arr,2);System.out.println(ret);}
}

二分查找:针对有序数组,我们还可以通过二分查找来找出要查找的数据的下标:
public class Demo3 {
// 二分查找:public static int binarySearch(int[] arr, int i){int left = 0;int right = arr.length - 1;while(left <= right){int mid = (right + left)/2;if(arr[mid] < i){left = mid + 1;mid = (right + left)/2;}else if(arr[mid] > i){right = mid - 1;mid = (right + left)/2;}else if(arr[mid] == i){return mid;}}return -1;}public static void main(String[] args) {int[] arr = {12,34,45,51,54,65,76,87,97,99};int ret = binarySearch(arr,51);System.out.println(ret);}
}

图解:

当然,我们也可以通过二分查找查找无序的数组的特定元素:先通过Arrays里面的sort方法对数组进行排序(升序),然后再通过二分查找查出排序好以后的特定数组的下标,不过这样做的意义其实并不大,因为经过排序,数组的下标早已不是原来的样子了。
数组排序(冒泡排序)
import java.util.Arrays;
public class Demo3 { //冒泡排序:public static void bubbleSort(int[] arr){for (int i = 0; i < arr.length-1; i++) {//一共要排arr.length-1次序,每排一次都会让数组中的一个数有序(此处以最大值为例)for (int j = 0; j < arr.length-i-1; j++) {//每一次排序内部要走arr.length-1-i次排序,才能实现让数组中为排好序的数里面的最大值排到最后if(arr[j]>arr[j+1]){int tmp = arr[j];arr[j] = arr[j+1];arr[j+1] = tmp;}}}}public static void main(String[] args) {int[] arr = {12,45,97,76,51,34,87,54,65,99};bubbleSort(arr);System.out.println(Arrays.toString(arr));}
}
由图可知,在i=4开始,数组就已经是有序的了,后面的比较就是冗余的了,所以我们可以再对这个代码进行优化:在方法中加一个变量用来判断是否发生了交换,且每有一趟循环走完开始下一趟循环的时候就要让这个变量变回到它原来的值。一旦发现不再发生交换的时候,就直接跳出循环。
import java.util.Arrays;
public class Demo3 { //冒泡排序:public static void bubbleSort(int[] arr){for (int i = 0; i < arr.length-1; i++) {//一共要排arr.length-1次序,每排一次都会让数组中的一个数有序(此处以最大值为例)boolean flg = false;//每一趟开始的时候都要让flg为falsefor (int j = 0; j < arr.length-i-1; j++) {//每一次排序内部要走arr.length-1-i次排序,才能实现让数组中为排好序的数里面的最大值排到最后if(arr[j]>arr[j+1]){int tmp = arr[j];arr[j] = arr[j+1];arr[j+1] = tmp;flg = true;//若发生交换,则改变flg的值,通过flg的值来确定是否发生交换,若未发生交换,则直接跳出循环}}if(flg == false){break;}}}public static void main(String[] args) {int[] arr = {12,45,97,76,51,34,87,54,65,99};bubbleSort(arr);System.out.println(Arrays.toString(arr));}
}
数组逆序
此处介绍的是直接通过交换对应下标的元素来实现数组逆序的效果。
import java.util.Arrays;
public class Demo3 { //数组逆序:public static void reserve(int[] arr){int left = 0;int right = arr.length-1;while(left < right){//不用管相等的情况,因为当right和left相等时就表明相等的那个数就是中间的那个,// 既然在最中间,也没有交换的必要了int tmp = arr[left];arr[left] = arr[right];arr[right] = tmp;left++;right--;}}public static void main(String[] args) {int[] arr = {12,45,97,76,51,34,87,54,65,99};reserve(arr);System.out.println(Arrays.toString(arr));}
}

二维数组
- 语法:数据类型[][] 数组名称 = new 数据类型[行数][列数]{初始化数据};
- int[][] arr = new int[][]{{1,2,3},{4,5,6}};
- int[][] arr = {{1,2,3},{4,5,6}};
- int[][] arr = new int[2][3];(默认这两行三列里面存的全是0)
- 二维数组本质上也是一个数组,只不过每个数组里面又是一个数组。行里面存放的是各个列组成的的数组的地址。

- 遍历二维数组:
- 我们很容易想到一个最简单粗暴的方法:通过两层循环来遍历整个数组:

- 但是很明显,对于这种方法,我们是自己手动置入其行和列的长度的。有没有办法可以获取到其行和列的长度吗?当然是有的。结合前面介绍的二维数组的元素其实就是一维数组,我们可以很好地理解下面这种写法:

- 我们很容易想到一个最简单粗暴的方法:通过两层循环来遍历整个数组:
- 顺便一提,要想直接打印出二维数组,我们使用的方法不再是toString,而是deepToString

- 不规则的二维数组:
- 注意,未对不规则二维数组初始化的时候不能打印它。因为二位数组里面存的是一维数组,而数组是引用类型,引用类型未初始化默认存储的是null,也就是不指向任何地址,所以会报空指针异常的错误。
Arrays中的其他方法的介绍:
- equals:判断两个数组是否一样:

- fill:帮助数组填充数据:

同时,fill方法有很多重载方法,可以根据需求选择,如:把某个值从数组的n1下标填充到n2下标
相关文章:
Java中的数组
前言: 本篇博客将为大家介绍Java中的数组的相关知识。 目录 基本介绍 概念相关 数组的使用 数组是引用类型 应用场景 保存数据 作为方法的参数 作为方法的返回值 练习 数组转字符串 数组拷贝 求数组中元素的平均值 查找数组中的指定元素(二…...
Java反射调用jar包实现多态
上一篇实现了反射调用jar包,但是没有实现多态,这次先给自己的jar包类抽象一个接口,然后实现类实现接口。最后调用放反射得到的对像转换成接口类型调用执行。 定义接口,指定包为ZLZJar package ZLZJar;public interface ITest {p…...
PowerBI 一些基础功能
1、PowerBI创建日期表 1.1、Power BI 日期表 - 知乎日期是做数据分析的时候使用最频繁的分析维度,一般建议建立单独的日期维度表,并与事实表的日期字段建立连接。 建立日期维度表可通过DAX函数的方式进行: 日期表 CALENDAR(DATE("2023&…...
Mac用命令行安装Adobe代码字体Source Code Pro
执行命令 brew tap homebrew/cask-fonts && brew cask install font-source-code-pro...
RustDay05------Exercise[31-40]
31.结构体申明 结构体在这里给了三种声明样式 (1)字典样式的键值对(使用花括号) (2)元组样式的数值元组(使用圆括号) (3)空结构体,可以被格式化输出名字 // structs1.rs // Address all the TODOs to make the tests pass! // Execute rustlings hint structs1 or use the…...
wireshark过滤器的简单介绍
wireshark过滤器的简单介绍 Wireshark的过滤器主要分为捕获过滤器和显示过滤器两种,其中捕获过滤器在数据包捕获时起作用,而显示过滤器用于在已捕获的数据包的集合中筛选数据。以下是一些Wireshark过滤器的详细介绍: 捕获过滤器:…...
数据结构:二叉树(1)
目录 树的概念 树的表示形式 二叉树 二叉树的性质 题目 二叉树的存储 链式存储 初始化二叉树 二叉树的遍历 前序遍历:根👉左子树👉右子树 中序遍历:左子树👉根👉右子树 后序遍历:左子…...
[nlp] chathome—家居装修垂类大语言模型的开发和评估
ChatHome: Development and Evaluation of a Domain-Specific LanguageModel for Home Renovation ChatHome: 家居装修垂类大语言模型的开发和评估 1、摘要: 我们的方法包括两个步骤:首先,使用广泛的家庭装修数据集(包括专业文章、标准文档和网络内容)对通用模型进行后预训…...
http(下)
http的工作流程: 客户端---服务端通信过程 请求----响应的模型 建立连接:tcp/ip协议与服务器建立连接(三次握手),客户端向服务器的80端口发送连接请求 发送请求:一旦连接建立之后,客户端就像…...
Python学习基础笔记七十二——IDE集成开发环境
集成开发环境,英文缩写是IDE。 IDE可以帮你更高效地开发项目代码。因为它提供了非常实用的功能,比如项目文件管理、语法高亮、代码导航、自动补齐代码、语法静态检查、调试、版本控制等等。 两款IDE:Pycharm和VSCode。 pycharm中的代码文件都…...
[MQ]Win平台RocketMQ安装启动
1、下载 官网下载地址:https://rocketmq.apache.org/zh/download 2、解压ZIP包 解压rocketmq-all-x.x.x-bin-release.zip到目录。 比如我解压到了E:\Env\MQ_rocket\rocketmq-all-5.1.4-bin-release 3、配置环境变量 ROCKETMQ_HOME 4、RocketMQ JVM内存配置 这个需要…...
vscode工程屏蔽不使用的文件夹或文件的方法
一. 简介 vscode是一款 微软提供的免费的代码编辑软件。 对于 IMX6ULL-ALPHA开发板而言,NXP官方uboot一定会支持不止 IMX6ULL芯片的代码,也不止支持 一种架构,还支持其他芯片或架构的源码文件。 为了方便阅读代码,vscode软件可…...
黑马JVM总结(三十四)
(1)JMM概述 (2)JMM-原子性-synchronized java内存模型是如何保证原子性的呢,它是通过synchroized关键字,来达到这个目的的 第一个线程来了进入同步代码块之后,把这个对象加上锁了,…...
[linux]vncserver常用终端命令合集
开启vnc服务:systemctl start vncserver:1.service 关闭vnc服务:systemctl stop vncserver:1.service 重启vnc服务:systemctl restart vncserver:1.service 设置VNC密码: vncpasswd 开启VNC: vncserver :1 关闭VNC࿱…...
亚马逊、eBay,速卖通,国际站买家账号支付异常问题解决方法
如何解决下单被砍、封号问题,建议采取以下措施: 买家账号下单,不单纯只是解决支付卡、IP问题就可以了,因为平台大数据风控点很多, 我们防关联具体要解决几个问题 一:要硬件参数的关联、安全码、地区码、…...
Constitutional AI
用中文以结构树的方式列出这篇讲稿的知识点: Although you can use a reward model to eliminate the need for human evaluation during RLHF fine tuning, the human effort required to produce the trained reward model in the first place is huge. The label…...
TDengine 资深研发整理:基于 SpringBoot 多语言实现 API 返回消息国际化
作为一款在 Java 开发社区中广受欢迎的技术框架,SpringBoot 在开发者和企业的具体实践中应用广泛。具体来说,它是一个用于构建基于 Java 的 Web 应用程序和微服务的框架,通过简化开发流程、提供约定大于配置的原则以及集成大量常用库和组件&a…...
数据结构-冒泡排序Java实现
目录 一、引言二、算法步骤三、原理演示四、代码实战五、结论 一、引言 冒泡排序是一种基础的比较排序算法,它的思想很简单:重复地遍历待排序的元素列表,比较相邻元素,如果它们的顺序不正确,则交换它们。这个过程不断重…...
完整教程:Java+Vue+Websocket实现OSS文件上传进度条功能
引言 文件上传是Web应用开发中常见的需求之一,而实时显示文件上传的进度条可以提升用户体验。本教程将介绍如何使用Java后端和Vue前端实现文件上传进度条功能,借助阿里云的OSS服务进行文件上传。 技术栈 后端:Java、Spring Boot 、WebSock…...
【微服务 SpringCloud】实用篇 · 服务拆分和远程调用
微服务(2) 文章目录 微服务(2)1. 服务拆分原则2. 服务拆分示例1.2.1 导入demo工程1.2.2 导入Sql语句 3. 实现远程调用案例1.3.1 案例需求:1.3.2 注册RestTemplate1.3.3 实现远程调用1.3.4 查看效果 4. 提供者与消费者 …...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能
指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...
篇章二 论坛系统——系统设计
目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...
