Java——数组的定义与使用

news2024/12/28 19:01:49

各位看官:如果您觉得这篇文章对您有帮助的话
欢迎您分享给更多人哦
感谢大家的点赞收藏评论,感谢您的支持
c74aa267346f4a60b3edbe51bce6243b.png!!!

一:数组的概念以及定义,初始化

1.1:数组概念以及定义

数组概念:可以看成是 相同类型元素的一个集合
数组定义:三种方法
T [] 数组名 = new T [ N ];例如:int[]arr = new arr[10];
T :表示数组中存放元素的类型
T[]:表示数组的类型
N :表示数组的长度
例如:
int [] array1 = new int [ 10 ]; // 创建一个可以容纳 10 int 类型元素的数组
double [] array2 = new double [ 5 ]; // 创建一个可以容纳 5 double 类型元素的数组
String [] array3 = new String [ 3 ]; // 创建一个可以容纳 3 个字符串元素的数组

1.2:数组的初始化主要有两种:动态初始化以及静态初始化

     1.静态初始化和动态初始化一步完成

数组动态初始化:在创建数组时,直接指定数组中元素的个数
int [] array = new int [ 10 ];这种初始化,这个arr数组里面的值都为0;
静态初始化:在创建数组时不直接指定数据元素个数,而直接将具体的数据内容进行指定
静态初始化虽然没有指定数组的长度,编译器在编译时会根据 {} 中元素个数来确定数组的长度
 语法格式: 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 int[];
直接就是  int [] array1 = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 };
但是这种初始化是严令禁止的: int [] array1 = new int [10]{ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 };, 编译器会报错误

     2.同时静态初始化和动态初始化也可以分为两步:

int [] array1 ;
array1 = new int [ 10 ];
int [] array2 ;
array2 = new int []{ 10 , 20 , 30 };
// 注意省略格式不可以拆分, 否则编译失败
// int[] array3;
// array3 = {1, 2, 3}; 这样不可以,!!!只能在定义的时候进行赋值
1.如果没有对数组进行初始化,数组中元素有其默认值:
2.如果数组中存储元素类型为引用类型,默认值为null


二:数组的使用:

1.1:数组的访问:

数组下表访问不能越界:

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

数组越界异常

1.2:数组遍历

1.一般C中我们都是循环遍历:但是java中注意在数组中可以通过 数组对象.length 来获取数组的长度

int [] array = new int []{ 10 , 20 , 30 , 40 , 50 };
for ( int i = 0 ; i < array . length ; i ++ ){
System . out . println ( array [ i ]);
}

2.java也可以使用for-each遍历数组:

int [] array = { 1 , 2 , 3 };
for ( int x : array ) {
System . out . println ( x );
}

2:数组是引用类型

2.1:要了解数组首先,要了解引用到底是什么?

在java里 数据类型分为两大类:基本数据类型(Primitive Types)和引用数据类型(Reference Types)。引用数据类型是相对于基本数据类型而言的,它们不是直接在内存中存储数据值,而是存储数据的引用(或者说是指向数据的内存地址)

Java中的引用数据类型主要包括以下几类:

类,数组,枚举,接口,注解

我们现在现在需要注意这两项:

  1. 类(Class Types)类是Java程序的基本构建块,用于创建对象。每个对象都是类的一个实例,而类本身就是一种引用数据类型。你可以定义自己的类来封装数据和逻辑,Java标准库中也提供了大量的类供我们使用。

  2. 数组(Array Types)数组是一种特殊的引用类型,用于存储固定大小的同类型元素。数组可以是基本数据类型的数组,也可以是引用数据类型的数组(比如对象数组或另一个数组的数组)。

2.2:初始JVM的内存分布:

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

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

基本数据类型创建的变量,称为基本变量,该变量空间中直接存放的是其所对应的值;
引用数据类型创建的变量,一般称为对象的引用,存储的是对象所在空间的地址的变量。
从上图可以看到, 引用变量并不直接存储对象本身,可以简单理解成存储的是对象在堆中空间的起始地址。通过该
地址,引用变量便可以去操作对象 。有点类似 C 语言中的指针,但是 Java 中引用要比指针的操作更简单。
再看一个例子:

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.
注意 : Java 中并没有约定 null 0 号地址的内存有任何关联

3:数组应用场景:

3.1:数组作为函数参数:一张图弄懂

总结 : 所谓的 " 引用 " 本质上只是存了一个地址(还不是真的内存地址) . Java 将数组设定成引用类型 , 这样的话后续进行数组参数传参 ,
其实只是将数组的地址传入到函数形参中. 这样可以避免对整个数组的拷贝 ( 数组可能比较长 , 那么拷贝开销就会很大 ).

3.2:数组作为函数的返回值

public class Test {
    public static int[] func(){
        int []array =  new int[]{1,2,3,4,5};
        return array;
    }
实话说这个array数组是个临时变量,在C里面func返回时会被销毁,但是在java里面这个还是一直存在的就不会销毁
    public static void main(String[] args) {
        int[] ret = func();
        for (int i = 0; i < ret.length; i++) {
            System.out.println(ret[i]);
        }
    }
}

4:数组练习:

4.1:数组转化为字符串Arrays.toString

 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 += ",";
            } else {
                ret += "]";
            }
        }
        return ret;
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4};
        String ret = myToString(arr);
        System.out.println(ret);
    }
}
注意ret是String类型,每次都是ret+=……,最后直接打印
但是 Arrays.toString这个方法直接帮我们数组转化为字符串:

 4.2:拷贝方法:Arrays.copyOf Arrays.copyOfRange

巧了,我们java里面已经帮我们实现好了:Arrays.copyOf这个方法(这个方法里面的参数(换个类型)还是有很多的,一起构成了方法的重载)
public static void main(String[] args) { //Arrays.copyOf(),Arrays.copyOfRange()
    int[] arr = {1, 2, 3, 4};
    int[] copy = Arrays.copyOf(arr, arr.length * 2);
//并且这里我们还可以进行两倍的拷贝,因为这个数组没有长度嘛,不用考虑越界的问题
    System.out.println(Arrays.toString(copy));
还可以选择拷贝:
    int[] copy2 = Arrays.copyOfRange(arr, 1, 2);但是这个是从arr数组内部拷过来的

    System.out.println(Arrays.toString(copy2));
}

这里大家可以发现打印的有12个因为是[1,13)左闭右开,,但是arr从1开始里面只有3个数,然后就只能copy3个数然后补0

那这些方法的源码是怎么实现的呢:大家可以看我这张图
但是源代码实现的话又会有一些的的问题:就不能拷贝上述的12个了
我们尽量还是用Arrays.copyOfRange这个方法
注意:
数组当中存储的是基本类型数据时,不论怎么拷贝基本都不会出现什么问题,但如果存储的是引用数据类 型,拷贝时需要考虑深浅拷贝的问题,关于深浅拷贝在后续详细给大家介绍

4.3:二分查找以及排序方法:

二分查找:针对 有序数组 ,返回的值返回的是最后一次的位置left然后 -(left+1)
所以说按下面这个数组,key每次都>10的话,每次返回都是-9
这是我模仿源码的方法写的
public class Test {
    public static void main(String[] args) {
        int []arr = {1,2,3,4,5,6,7,8,9};
        int key =7;
        int ret = binarySearch(arr,arr.length,key);
        System.out.println(ret);
    }
    public static int binarySearch(int []arr,int sz,int key){
        int left = 0;
        int right = sz-1;
        while(left < right){
            int mid = (left +right)>>>1;//这个右移一位就很秒
            if(arr[mid] < key){
                left = mid + 1;
            }
            else if(arr[mid]>key){
                right = mid -1;
            }else{
                return mid;
            }
        }
        return -(left+1);
    }

}
源码:
但是如果不是有序地呢,我们可以自己实现一个冒泡排序 以及配合的找数字的,但是java里面已经帮我们实现的有方法了——Arrays.sort
以及配合找数字的Arrays.binarySearch
不过返回的值就是拍完序之后的位置了,这个一定要注意!!!
二分查找优点:针对一个长度为 10000 个元素的数组查找 , 二分查找只需要循环 14 次就能完成查找 . 随着数组元素个数 越多, 二分的优势就越大 .

4.4:填充方法以及比较方法:

填充也可以指定范围:java 太妙啦!!!

4.5:数组求平均值

代码两个注意点

1:首先使用 for -each遍历数组时,这里的X其实就是数组里面的值

2:最后求平均值一定要强转成double 类型

public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6};
System.out.println(avg(arr));
}
public static double avg(int[] arr) {
int sum = 0;
for (int x : arr) {
sum += x;//注意这个
}
return (double)sum / (double)arr.length;//注意
}

三:二维数组的使用

1.二维数组的4种定义方式

二维数组是特殊的一维数组

二维数组的定义方法:一般就是这三种

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

但是二维数组还可以不指定列,只指定行(和C语言相反)(第四种)

        int [][] array = new int[2][];
        String ret = Arrays.toString(array);
        System.out.println(ret);

(这个时候就相当于,只初始化了两个值,array[0],array[1],他们两个的值默认都是null(这个时候就完全可以看出来array(二维数组就是特殊的一维数组)))

然后我可以这样给他赋值

        int [][] array = new int[2][];
        array[0] = new int[]{1,2,3};
        array[1] = new int[]{1,2,3,4,5,6};

2.二维数组的遍历:

我们上述描述过了一维数组(array)的长度是array.length,我们现在又知道了二维数组又是特殊的一维数组譬如上述的array[2][],那么它的长度就是array.length,它经过初始化之后array[1].length就是3

那么我们有了上述的知识之后就可以写出下面的代码

        int [][] array = new int[][]{{1,2,3},{4,5,6}};
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                System.out.print(array[i][j]+" ");
            }
            System.out.println();// 打印一行换行
        }

3.二维数组的打印

那我们这样打印呢?

        int [][] array = new int[][]{{1,2,3},{4,5,6}};
        System.out.println(array[0]);
        System.out.println(array[1]);
打印的不是实际的地址是经过修改的地址,实际上是
最后调用的是 toString方法
再看看接下来打印的是什么呢?
        int [][] array = new int[][]{{1,2,3},{4,5,6}};
        System.out.println(array[0]);
        System.out.println(array[1]);
        System.out.println("=============");
        System.out.println(Arrays.toString(array[0]));
        System.out.println(Arrays.toString(array[1]));
        System.out.println("=============");
        System.out.println(array[0].length);
        System.out.println(array[1].length);
        System.out.println("=============");
        System.out.println(array.length);
        System.out.println("=============");
这个呢?
        int [][] array = new int[][]{{1,2,3},{4,5,6}};
        System.out.println(Arrays.toString(array));
        System.out.println(Arrays.deepToString(array));

上述就是的Java—数组的使用和定义全部内容了,相信您能看到这里,一定是对小编有了一定的认可,如果有任何错误
 欢迎各位大佬评论区留言修正或者直接私信我!!!
您的支持就是我最大的力量
​​​
bcb51650eac54f748f693cdc5b00f9a6.png2d8b40093abe47c7b347cdd7c906e87f.gif

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

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

相关文章

红黑树:c++实现

1. 红⿊树的概念 红⿊树是⼀棵⼆叉搜索树&#xff0c;他的每个结点增加⼀个存储位来表⽰结点的颜⾊&#xff0c;可以是红⾊或者⿊⾊。 通过对任何⼀条从根到叶⼦的路径上各个结点的颜⾊进⾏约束&#xff0c;红⿊树确保没有⼀条路径会⽐其他路 径⻓出2倍&#xff0c;因⽽是接近平…

用LaTeX写一篇帅帅的算法学习题解

前言 先来看看用 LaTeX \text{LaTeX} LaTeX 写出来的题解是啥样&#xff0c;内容是瞎写的。 前提知识与环境 默认已经掌握了 LaTeX \text{LaTeX} LaTeX 的一些用法&#xff0c;特别是公式如何写&#xff0c;如果你对这块还是很了解&#xff0c;可以先学着使用 Typora \…

DEEP TEMPORAL GRAPH CLUSTERING.md

ICLR23 推荐指数&#xff1a; #paper/⭐ 原因的话&#xff0c;可以找找前人的一篇文章(可以看&#xff0c;但是当你阅读前人文章会发现。) 动机/优点 很明确&#xff0c;时序图只需要考虑时间相近的点&#xff0c;因此开销特别小。但是邻接矩阵&#xff0c;就要考虑所有点的关…

Dockerfile最佳实践:如何创建高效的容器

在微服务和云计算时代&#xff0c;Docker就已经成为应用开发和部署不可或缺的工具。如今虽处大模型时代&#xff0c;但这些基础技术仍然是我们需要掌握的。 容器化允许开发者将应用程序及其依赖打包到一个单一的、可移植的单元中&#xff0c;确保了可预测性、可扩展性和快速部…

反射机制(Reflection)

1. 反射 Java的反射机制(reflection)是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意方法和属性&#xff1b;这种动态获取信息以及动态调用对象方法的功能称为java语言的反…

创建一个c#程序,实现字符串类型转整数类型

首先&#xff0c;创建一个c#程序 在代码编辑器中编写代码&#xff0c;点击Run按钮或者按下F5键来运行程序。 下面&#xff0c;编写将字符串类型转换为整数类型的代码。 sing System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Task…

安装samples/1_Utilities/deviceQuery等文件

本文章摘抄来自https://zhuanlan.zhihu.com/p/666647168 从cuda11.6开始cuda toolkit就不自带cuda-samples了&#xff0c;而deviceQuery又是cuda-sample的一个子库&#xff0c;所以需要自己手动装一下。 我的系统是ubuntu20.04&#xff0c;已经安装了CUDA Toolkit 12.2。 第…

【深度学习】使用FasterRCNN模型训练自己的数据集(记录全流程

此处用的FasterRCNN模型使用的是B导的源码&#xff0c;读者可以去B站搜B导的视频进行了解和学习&#xff0c;视频中B导非常细心讲解了如何训练自己的数据集以及预测。 文章目录 前言一、准备数据集二、环境配置2.1 基础环境2.2 其他依赖包安装2.3 预训练权重下载 二、训练数据集…

程序员成长秘籍:是迈向管理巅峰,还是深耕技术架构?

专业在线打字练习平台-巧手打字通&#xff0c;只输出有价值的知识。 一 管理和架构 做技术的同学一般有两条职业发展路径&#xff0c;横向的管理路线和纵向的技术路线。管理路线对应的是管理岗&#xff0c;讲究的是排兵布阵&#xff0c;通过各种资源的优化配置发挥价值。技术路…

(Linux驱动学习 - 10).MISC驱动实验

一.MISC介绍 1.MISC定义 misc 的意思是混合、杂项的&#xff0c;因此 MISC 驱动也叫做杂项驱动&#xff0c;也就是当我们板子上的某 些外设无法进行分类的时候就可以使用 MISC 驱动。 MISC 驱动其实就是最简单的字符设备驱 动&#xff0c;通常嵌套在 platform 总线驱动中&…

智能贴身监测,健康生活建议,圆道妙医智能手表体验

如今热衷于运动和健康生活的爱好者越来越多&#xff0c;相关的赛事等活动也是逐年增多&#xff0c;很多朋友为了能够直观的了解自己的健康状况&#xff0c;都会配备一款智能手表&#xff0c;这样戴在身上就可以随时了解自己的心率、血氧等数据。最近我尝试了一款圆道妙医推出的…

MobaXterm连接Cloudflare Tunnel内网穿透的SSH

背景 如官方文档所示&#xff0c;Cloudflare Tunnel要求我们对SSH客户端进行配置&#xff0c;使本地的cloudflared软件代理SSH才能连接。 存在问题 由于MobaXterm的Session实质为嵌入式PuTTY&#xff0c;不使用OpenSSH样式的配置文件&#xff08;即~/.ssh/config&#xff09…

SpringBoot框架下购物推荐网站的设计模式与实现

3系统分析 3.1可行性分析 通过对本东大每日推购物推荐网站实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本东大每日推购物推荐网站采用JAVA作为开发语言&…

对层级聚类树进行模块分割,定位基因在哪个模块中

拷贝数据到 ImageGP (http://www.ehbio.com/Cloud_Platform/front/#/analysis?pageb%27Ng%3D%3D%27)&#xff0c;并设置参数. ID untrt_N61311 untrt_N052611 untrt_N080611 untrt_N061011 trt_N61311 trt_N052611 trt_N080611 trt_N061011 ENSG000…

【ROS2实操二】服务通信

简介 服务通信也是ROS中一种极其常用的通信模式&#xff0c;服务通信是基于请求响应模式的&#xff0c;是一种应答机制。也即&#xff1a;一个节点A向另一个节点B发送请求&#xff0c;B接收处理请求并产生响应结果返回给A。比如如下场景&#xff1a;机器人巡逻过程中&#xff0…

cuda入门学习

最近接触cuda 编程&#xff0c;记录一下。 1 工作实现一个【0-100&#xff09;的加法 如果用python sum 0 for i in range(200):sumi print(sum)2 cuda 的一些简单的概念 一维情况下大概是这样的 (1个grid * 2个blocks * 4个thread) 3 代码直接上代码 我把100分为20个b…

Jenkins---01

什么是敏捷开发 敏捷开发以用户的需求进化为核心&#xff0c;采用迭代、循序渐进的方法进行软件开发。在敏捷开 发中&#xff0c;软件项目在构建初期被切分成多个子项目&#xff0c;各个子项目的成果都经过测试&#xff0c;具备可视、 可集成和可运行使用的特征。换言之&…

2024年编程资料【9月份部分】

资料列表 「CSDN会员免费电子书1000本」 https://pan.quark.cn/s/5019390a751a 【黑马程序员】年度钻石会员-人工智能AI进阶 https://pan.quark.cn/s/1d14a2a179c2 JavaScript从入门到高级教程 - 带源码课件 https://pan.quark.cn/s/c16ed07eac93 【马哥教育】云原生微服务治理…

测试常用插件: ModHeader - Modify HTTP headers插件进行IP模拟/IP欺骗

由于公司是做海外项目的&#xff0c;所以付款时有要求进行模拟不同IP登录进去时会优先显示该地区的支付方式。 1.安装插件 这里以Microsoft Edge为例&#xff0c;打开扩展 搜索&#xff1a;ModHeader - Modify HTTP headers&#xff0c;进行获取安装即可 安装完成后&#xff…

CVESearch部署、使用与原理分析

文章目录 前言1、概述2、安装与使用2.1、源码安装2.1.1、部署系统依赖组件2.1.1.1、下载安装基础组件2.1.1.2、下载安装MongoDB Community Edition 7.0 2.1.2、使用源码安装系统2.1.2.1、安装CVESearch2.1.2.2、填充MongoDB数据库2.1.2.3、填充Redis数据库 2.2、使用方法 3、测…