零基础Java第八期:一维数组(1)

ops/2024/10/20 21:10:06/

目录

一、 一维数组的基本概念 

1.1. 什么是数组

1.2. 数组的创建及初始化

1.3. 数组的使用

二、数组是引用类型

2.1. 初始JVM的内存分布

2.2. 基本类型变量与引用类型变量

 2.3. 引用变量的理解

2.4. null 

 三、数组的应用场景

 3.1. 作为函数的参数

3.2. 作为函数的返回值


一、 一维数组的基本概念 

1.1. 什么是数组

       当我们需要存储多个类型相同的变量时,如果一个一个去创建会很麻烦 ,此时我们就可以使用数组去简化这类问题。数组:可以看成是相同类型元素的一个集合。在内存中是一段连续的空间,地址是连续存放的。每个空间有自己的编号,第一个位置的编号为0,即数组的下标。

1.2. 数组的创建及初始化

 (一)数组的创建规则:

数据类型 [] = new 数据类型[N],其中N表示数组的长度。

java">        int[] array1=new int[10];//表示一个可容纳10个int型的数组double[] array2=new double[20];//表示一个可容纳20个double型的数组String[] array3=new String[30];//表示一个可容纳30个String性的数组

 (二)数组的初始化 

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

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

java">int[] array=new int[10]

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

java">        int[] array4 = new int[]{0,1,2,3,4,5,6,7,8,9};double[] array5 = new double[]{1.0, 2.0, 3.0, 4.0, 5.0};String[] array6 = new String[]{"hell", "Java", "!!!"};

       注意:1.静态初始化虽然没有指定数组的长度,编译器在编译时会根据{}中元素个数来确定数组的长度   2.静态初始化时, {}中数据类型必须与[]前数据类型一致   3.静态初始化可以简写,省去后面的new T[]。

       如果没有对数组进行初始化,数组中元素有其默认值。如果数组中存储元素类型为基类类型,默认值为基类类型对应的默认值。 

类型默认值
byte0
short0
int0
long0
float0.0f
double0.0
char/u000
booleanfalse
Stringnull

        在这里我们只演示boolean和String类型的默认值,代码如下,对此代码进行调试,运行最后一行时,我们就可以看到boolean的默认值为false

java">    public static void main(String[] args) {boolean[] array=new boolean[3];//默认值为falseSystem.out.println("=====");String[] str=new String[3];}

 

1.3. 数组的使用

(1)数组元素的访问 

      数组是一段连续的内存空间,因此支持随机访问,即通过下标访问快速访问数组中任意位置的元素 ,即我们可以通过下标来进行打印、修改,并且不能越界访问,否则会出现如下报错。

java">        int[] arrays=new int[]{1,2,3,4};arrays[2]=10;System.out.println(arrays[1]);//打印元素System.out.println(arrays[2]);//修改元素System.out.println(arrays[4]);//越界访问

(2)遍历数组:将所有元素都访问一遍。

       如果我们一个一个打印,或者对里面的元素进行修改,会非常麻烦。此时我们可以使用for循环来解决。

java">        int[] arrays = new int[]{1,2,3,4,5,6};for(int i=0;i<=5;i++){System.out.println(arrays[i]);}

     我们来对此代码进行调试,当运行到“System.out.println(arrays[i]);”时,就会产生如下图所示。

       虽然for循环可以帮助我们解决上面提到的问题,但是我们无法获取数组的长度。那我们就可以通过下面的代码来进行实现。

java">        int[] arrays = new int[]{1,2,3,4};for(int i=0;i< arrays.length;i++){System.out.print(arrays[i]);}System.out.println();for (int x:arrays) {System.out.println(x);}

      第一种是for循环,原理不必多说;第二种是for-each,原理是遍历数组,将数组中的元素赋值给x,但这种方法无法获取数组元素的下标,也无法对下标进行运算。

     当然还有第三种打印方式,是由Java官方提供操作数组的工具,代码如下:

java">import java.lang.reflect.Array;
import java.util.Arrays;public class Main {public static void main(String[] args) {int[] arrays=new int[]{1,2,3,4,5};String ret=Arrays.toString(arrays);System.out.println(ret);}
}

         Array需要导入一个Arrays的包,我们可以查看一下toString的源码,是String类型的,所以使用String ret来接收一下,直接打印ret就可以了。 下图为打印结果。

二、数组是引用类型

2.1. 初始JVM的内存分布

       我们经常说数组是引用变量,数组里的元素是如何储存在数组里的呢?要想搞清楚这两个问题,那我们首先需要了解JVM的内存分布。

       我们可以把JVM理解为一个大房子,房子分为客厅、厨房、卧室、厕所。同样,JVM也可以划分出多个内存空间,如下图所示。设想一下,如果我们的房子非常乱,找起东西来就会很麻烦。如果对内存中存储的数据不加区分的随意存储,那对内存管理起来将会非常麻烦。 

2.2. 基本类型变量与引用类型变量

       基本数据类型创建的变量,称为基本变量,该变量空间中直接存放的是其所对应的值;而引用数据类型创建的变量,一般称为对象的引用,其空间中存储的是对象所在空间的地址。 好,我们来看下面一组代码:

java">public static void main(String[] args){int a = 1;int[] arrays = {1,2,3,4,5};

      arrays就是一个局部类型的引用变量,数组里的元素会在堆上有一个地址,arrays这个变量就会在栈上存这个地址;a也是main方法里的局部变量,它只会在栈上开辟内存空间,就不会在堆上。所以引用变量并不直接存储对象本身,可以简单理解成存储的是对象在堆中空间的起始地址。通过该 地址,引用变量便可以去操作对象。

 

 2.3. 引用变量的理解

看下面一组代码:

java">    public static void main(String[] args) {int[] array1 = new int[3];array1[0] = 10;array1[1] = 20;array1[2] = 30;int[] array2 = new int[]{1,2,3,4,5};array2[0] = 100;array2[1] = 200;array1 = array2;//重点,必须理解array1[2] = 300;array1[3] = 400;array2[4] = 500;for (int i = 0; i < array2.length; i++) {System.out.println(array2[i]);}}

       array1=array2,相当于我们把array2的地址赋给了array1,则array1就不能存原来的地址,这样就会造成两块引用同时指向一个空间,相当于通过array1去修改并访问array2,所以说打印出来的值则为100、200、300、400、500。那array1之前所指向的内存空间呢?答案是被回收掉了。

2.4. null 

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

java">public class Main {public static void main(String[] args) {int[] array1 = {1,2,3};System.out.println(array1);//打印结果是16进制的地址int[] array2 = null;//array2属于引用类型,默认值不能为0
//      array引用不指向任何对象System.out.println(array2.length);//null不指向任何对象,运行就会显示空指针异常}
}

     博主还留下了两个问题给你去思考:1、引用可以指向引用吗? 2、一个引用可以指向多个对象吗?好,第一个问题:array1=array2,上面我们提到了,array1指向的是array2所指向的对象。第二个问题:一个引用只能指向一个对象,比如 int a=10,不能说a在栈上存储了10个数据吗。

 三、数组的应用场景

 3.1. 作为函数的参数

java">public class Main {public static void print(int[] array){for (int i = 0; i < array.length; i++) {System.out.print(array[i]);}System.out.println();}public static void main(String[] args) {int[] array={1,2,3};print(array);}
}

        虽然两个引用都指向了同一个对象,但两个引用的作用域不一样,上面的array是形参,下面的array是实参 ,打印出来的结果就是1 2 3。在这种情况下,我们修改形参的值, 不影响实参的值。那如果我们来看下面一组代码,参数传数组类型呢?

       两个方法都是传递引用类型,第一个方法改变了形参的地址,形参的指向被改变了;而第二个方法中,形参修改了指向对象的内容。 

java">public class Main {public static void func1(int[] array){array =new int[]{10,20,30,40,50};}public static void func2(int[] array){array[0]=10;}public static void main(String[] args) {int[] array={1,2,3};func1(array);print(array);main1(args);//在main方法中,我们调用main1,就可以同时运行main和main1}public static void main1(String[] args) {int[] array={1,2,3};func2(array);print(array);}

 

3.2. 作为函数的返回值

我们都知道调用方法时,只能返回一个值,那我们可以使用数组来进行多个返回值的接收,代码如下:利用ret来接收,并返回给array。

java">import java.util.Arrays;public class Main {public static int[] test(){int[] ret=new int[2];ret[0]=10;ret[1]=20;return ret;}public static void main(String[] args) {int[] array=test();System.out.println(Arrays.toString(array));}
}

 


http://www.ppmy.cn/ops/127091.html

相关文章

C#中的信号

在C#中,信号是用于线程间同步的工具,允许线程通过信号进行等待和通知,以控制并发执行。以下是几种常见的信号工具及其用法: 1. ManualResetEvent 和 AutoResetEvent 这两个类都是基于信号量的同步原语。它们都允许线程等待某个信号并决定何时继续执行,区别在于事件被触发…

rabbitmq 工作队列模式

工作队列模式 一、原理流程图 二、基本知识 工作队列模式&#xff08;Work Queue Model&#xff09;是一种消息队列模型&#xff0c;生产者将任务分发到队列中&#xff0c;多个消费者从队列中按顺序获取并处理任务。该模式主要用于负载均衡&#xff0c;确保任务能够均匀分配给…

ParallelsDesktop20最新版本虚拟机 一键切换系统 游戏娱乐两不误

让工作生活更高效&#xff1a;Parallels Desktop 20最新版本虚拟机的神奇之处 大家好&#xff01;&#x1f44b; 今天我要跟大家安利一款让我工作效率飞升的神器——Parallels Desktop 20最新版本虚拟机。作为一个日常需要在不同操作系统间来回穿梭的人&#xff0c;这款软件简直…

白嫖正版xshell和XFTP

在哪里可以下载正版免费的xshell和XFTP&#xff0c;并且还能够获得官网免费持久更新 白嫖步骤 首先直接在浏览器搜索xshell官网 点进官网之后直接点击下载 接着点击免费授权页面 进入之后就可以免费下载了 下载安装完成后填写用户名和邮箱并提交&#xff0c;这里就以xshell为…

os.popen模块

一、前言 有时候在写一些脚本的时候&#xff0c;需要执行一些系统命令(windows/linux),因为这边会比较方便。用python原生的办法就比较复杂。下边就介绍集中常见的方法 二、os.system os.system是python 内置模块&#xff0c;执行命令非常简单。可以将要执行的命令传递进去。…

京存助力北京某电力研究所数据采集

北京某电力研究所已建成了一套以光纤为主&#xff0c;卫星、载波、微波等多种通信方式共存&#xff0c;分层级的电力专用的网络通信架构体系。随着用电、配电对网络的要求提高&#xff0c;以及终端通信入网的迅速发展&#xff0c;迫切地需要高效的通信管理系统来应对大规模、复…

(37)使用MATLAB画出余弦波的频谱

文章目录 前言一、MATLAB仿真代码二、仿真结果画图 前言 首先使用MATLAB生成一段余弦信号&#xff0c;然后对其进行FFT变换&#xff0c;画出其频谱。 一、MATLAB仿真代码 代码如下&#xff1a; f [50, 100]; % 两个余弦波的频率 fs 1000; …

『Mysql集群』Mysql高可用集群之读写分离(二)

前言 主从复制: 解决了Mysql的单点故障问题以及提高MySQL的整体服务性能. 读写分离: 解决的是数据库的读性能问题,分担主库的压力&#xff0c;提高系统的可用性和稳定性。 分库分表: 数据库分表可以解决单表海量数据的查询性能问题&#xff0c;分库可以解决单台数据库的并发…