推广 热搜: csgo  vue  angelababy  2023  gps  新车  htc  落地  app  p2p 

来吧!给你不一样的数组深入讲解!

   2023-07-09 网络整理佚名1260
核心提示:这里就要看数组的一些特点了,对于数组啊,人家是有序数据的集合,在内存中来展示就是人家需要连续的内存空间,还有一个特点那就是你一旦声明就不会再改变了我们上面已经简单介绍完数组了,那你知道什么是数组变量什么是数组对象吗不是说数组不能用new的方式创建吗,那应该不是吧,感觉和平常的对象不一样啊很懵圈啊,之前我还想使用Array来创建数组嘞是的,你看,比如说给数组数据进行排序

庆哥:这个涉及到数组的声明。 数组用于存储数据。 如果我们想使用它,我们必须首先创建它。 正如我之前所说,人们不使用 new,他们使用这种形式

int[] a = new int[10];

那么这样可以吗?

int[] a = new int[];

有什么区别?少了一个10好吗? 让我们来看看

我明白了,不,为什么不呢,想一想?

小白:嗯,这里的10是给数组指定长度,默认长度不可以是0吗?

青哥:这里我们需要看一下数组的一些特性。 对于数组来说,它们是有序数据的集合。 为了在内存中显示它们,它们需要连续的内存空间。 另一个特点是一旦你声明它们,它们就不会再改变

小白:嗯,这个我知道了,数组一旦确定了,就固定了,哦,我知道了,那么这里一定要指定长度,不然就相当于没有创建数组,而且长度为0是没有意义的

数组在内存中的分配

庆哥:对啊,我们再看一下这段代码

int[] a = new int[10];

这是怎么回事,首先我们知道,这是创建一个数组,长度也指定了,是10,对了,这里忘了说了,这个数组是一个整型数组,类型是int,我们为什么这么说? ,稍后详细讲,我们先看图

你是什​​么意思? 这些格子可以看成是内存,一块内存,现在我们创建一个长度为10的整数数组,那么我们就需要十个这样的内存空间。

小白:这里的红块是什么意思?

庆哥:红色,代表已经使用的内存空间。 你看到什么问题了吗? 现在你创建这样的代码

int[] a = new int[10];

意思就是你告诉内存,“内存里的家伙,给我十块内存空间,记住一定要连续”,也就是说数组申请的内存空间是连续分配的,数组中的数据就比较虚伪了。 彼此相邻

简单的聊天初始化

小白:嗯,我记得数组的声明不止一个吧?

青哥:是的,我们之前介绍过的叫动态初始化数组。 这是什么意思? 指定了长度,但没有给出值。 让我们看看这个

 int[] a = new int[10];
System.out.println(a[2]);

输出是0,你可以试试,这10个数据都是0,这是默认的初始化值,我们也可以用这个静态初始化

int[] b = new int[]{1, 2, 3};

什么意思呢,就是这个值是在数组创建的时候就确定的。 猜猜这样创建的数组的长度是多少?

小白:这个,这里没有给出10这样的数据,应该是这个。 。 。 3、后面的大括号里有三个数字

庆哥:我们看一下这段代码

int[] b = new int[]{1, 2, 3};

System.out.println(b.length);

这是什么啊,这是求数组的长度,我们看一下输出

你说得对,这样,它会根据你大括号里的数据来创建内存空间,也就是说,数字多了就申请几个内存空间,没有了或者就固定了较少的应用程序。

数组变量和数组对象

青哥:上面我们简单介绍了数组,你知道什么是数组变量,什么是数组对象吗?

小白:我去,晕,这对双胞胎

青哥:那我告诉你,什么是数组变量? 看前面的代码

int[] a = new int[10]

这个a其实是一个数组变量,数组变量指向一个数组对象,而数组变量其实是一个引用,里面存储的是内存地址,即引用等于内存地址,而内存地址是为了计算机看到的,而引用是给我们看的(我们比较熟悉的一个符号),而这个a其实就是数组的首地址,而指向的数组对象其实就是数组对应的数组对象变量a[0]。

数组对象实际上就是存储在内存空间中的值。

数组初始化初始化给谁

然后我们来谈谈数组变量和数组对象。 谁来初始化数组其实很简单。 知道了什么是数组变量和数组对象之后,我们应该知道数组初始化并不是数组变量的初始化。 相反,数组对象被初始化。

所谓数组对象的初始化,无非就是告诉内存,如果我要创建一个数组,你就得分配一块连续的内存给我。

你怎么样,明白吗?

小白:好的

数组可以存储什么

庆哥:好了,上面就是数组的基础知识了,就不多说了。 接下来我们来说说数组的数据存储类型。 还记得我之前说过的话吗? 数组中的每个元素都具有相同的类型。 上面我们是int类型的。 你是什​​么意思? 也就是说,你创建什么类型的数组就只能存储什么类型的数据。

例如,这将不起作用

因为您创建了一个 int 整数,所以只能存储整数数据,而不能存储字符串。 如果要存储字符串,则需要创建字符串数组

 String[] strings = new String[]{"hello"};

有一点例外

这里有一个例外,我们来看一下:

Object[] objects = new Object[10];
objects[0] = 1;
objects[1] = "hello";

这很好,我知道为什么不可以

小白:这个我知道,但是它是java中所有类的超类。

庆哥:正确答案,好吧,我们简单总结一下:

Java中的数组是一种用于存储相同数据类型的数据结构。 一旦初始化完成,内存中的空间就已经固定了。

数组是一个对象吗?

庆哥:你是说数组是对象吗?

小白:数组也是对象?不是说数组不能用new创建吗? 不应该是这样的。 感觉与普通物体不同。

青哥:说实话,数组其实是一个特殊的对象,只是数组比较特殊而已。 它与普通物体不同。 和普通对象一样,也有特定的java类。 比如我这里创建了一个类,然后有这样的代码:

 Person person = new Person();
System.out.println(person.getClass().getName());

就是创建一个对象,然后获取它的类名,如下

让我们再看看

Object object = new Object();
System.out.println(object.getClass().getName());

你知道这个,它的类名一定是,让我们看看

对了,我们再看一下数组,可以这样获取

//数组是特殊的对象,没有对应的类文件,数组类是在运行时产生的,类名很奇怪
System.out.println(new int[2].getClass().getName());

它的类别是什么?

在此插入图片描述

这是什么

小白:我走吧,我这里只要记住就可以了,其实数组也是一种特殊的对象。

庆哥:是的,你只要记住数组实际上是一个对象就可以了。 这是对数组的深刻理解。 那我们继续讲一下数组的两类容易混淆的事情。

数组和

这两个你熟悉吗?

小白:我很困惑。 之前想用Array来创建数组。

青哥:哈哈,不可能用它来创建数组吧。 这两个东西是干什么用的? ,我们先来看一个简单的例子,比如我们创建一个数组

 int[] b = new int[]{1, 2, 3};
System.out.println(Array.get(b, 1));

你看,我们通常使用b[1]来获取下标为1的元素,而我们可以像上面那样使用Array来获取,也就是说Array为我们提供了一些可以直接操作数组的方法,如下:

小白:这是一个类似的工具类,它可以方便我们操作数组吧?

青哥:对,记得我们之前说过这个阵法的。 它的构造方法是私有的,无法实例化。 它的方法也是静态的,可以通过类名直接调用,就像上面那样,它的存在是为了我们更方便地操作数组。

小白:这么说的话,是不是很像?

青哥:是的,也是一个方便我们操作数组的工具类,但是它们提供的功能不一样。 我们可以用它来给数组填充数据,即赋值,还可以进行排序、二分查找、截取等操作。 数组等

小白:这个提供了很多功能。 使用起来和Array类似吗?

青哥:对,看一下,比如对数组数据进行排序

System.out.println("排序:");

int[] array1 = new int[]{5, 7, 8, 9, 1, 3, 6};
Arrays.sort(array1);

看它提供的方法

在此插入图片描述

有很多,我们需要什么就用什么

怎么样,经过这样的介绍,你是不是发现这两个货其实并不难呢?

小白:对了,原来是有两个辅助。

数组的特点

庆哥:说到这里,你能总结一下数组的一些简单的特点吗?

小白:嗯,数组,连续内存分配,可以随机访问。 这次我刚刚了解到的是数组实际上是一个对象。 顺便说一下,数组也是有下标的,下标是从0开始的。

庆哥:好了,问题来了,为什么要从0开始,你知道吗?

为什么下标索引从0开始呢?

小白:这个我还真不知道。 我一般记得下标是从0开始的,至于为什么从0开始,我还真不知道。 怎么了,庆哥。

庆哥:要明白这个问题,你需要看这张图

我们已经知道数组的创建需要连续的内存空间。 比如这里的整型数组长度为10,那么在内存中开辟对应的内存空间。 在内存空间中,每个内存都有一个对应的地址。 ,这就是操作系统所做的事情。 当你申请内存时,操作系统会对内存地址进行编号。

例如,这里应用一个长度为10的整数数组。 我们知道java中int占用4个字节,也就是说一个数据占用4个字节的内存,也就是上面的块。

那么每个块都有一个对应的内存地址号。 例如0对应的块编号为1000-1003,占用四个字节。 接下来我们再结合数组的随机访问,比如我们使用array[0]来访问第一个元素,实际上是指向内存地址1000,也称为数组中的首地址,而数组变量array 指向这个首地址。

这个首地址也叫,记住这个,然后如果我们要访问下标1,怎么访问呢,这里有一个寻址公式

数组[i] = +i*

我们知道它是什么,它是什么? 其实,即使数据类型的字节长度,例如这里的int整数是4个字节,即4,我们现在要访问下标为1的数据,代入公式为:

数组[1] = 1000 + 1*4 = 1004

检查是否正好定位到下标为1的内存位置。

想一想,如果索引从1开始,那么查看的寻址是不是就变成了

数组[i] = + (i-1)*

这就需要多一步操作,浪费性能。

你怎么理解

小白:嗯,原来是这样,我终于学会了

数组的增删改查

青哥:好,我们看一下数组的增删改查,也就是对数组的一些基本操作。 首先我们看一下数组的加法。 我们看这张图来说说

如果我们想添加一个元素怎么办?

小白:这个可以分几种情况,前面插,中间插,最后插。

庆哥:插在中间怎么办? 您发现任何问题了吗?

小白:是的。 。 让我看看。 .数组的内存是连续分配的。 如果你想插入一个新元素,那么你必须将当前位置的元素及其后面的所有元素向后移动,以便为当前元素腾出空间。

青哥:是的,所以对于数组来说,不仅是插入,删除也是一样的。 如果不是尾部操作,则需要进行数组移动操作。

小白:那这可要费很大力气啊。

青哥:是的,所以数组的插入和删除效率不高。 最坏情况下,时间复杂度为O(n)。 好的情况下是尾部操作,O(1)。 你知道这个

小白:是的,我知道,搜索效率不是很高吗?

青哥:这里我想大家都有一个误区,什么,如果使用下标来访问数组,自然是高效的,但是我们通常是根据值来查找,而不是全部下标,所以我们需要遍历数组来查找我们想要的东西。想要,这需要被理解

小白:是的,我现在知道你这么说了

数组扩展

庆哥:对了,你想想,如果阵满了怎么办?

小白:嗯,当数组满了的时候,就无法插入新的元素了。 在这种情况下,需要对数组进行扩展。 对于这个扩展,我认为一旦数组被初始化,它将保持固定。 创建一个数组

青哥:是的,数组一旦初始化,内存中的空间就固定了。 即使清除某个元素,它所占用的空间仍然保留,因此数组的长度无法更改。 如果要改变数组的空间,就必须扩展数组。

小白:那我们需要把原数组中的数据全部复制吗?

庆哥:有的,有下面的简单代码

小白:哦,原来如此

超过! ! !

ps:数组怎么说呢,反正写起来有点蛋疼,已经是深夜两点了,先到这里吧,如有疑问欢迎留言讨论!

谢谢阅读

大家好,我是青小白哥哥。 一路走来,我积累了很多的学习经验和方法,收集了很多优质的学习资源。 现在我维护着一个公众号【 】,这意味着我已经脱离了。 不断学习,主要分享java技术相关的原创文章。 现在主要写数据结构与算法、计算机基础、线程与并发、虚拟机等方面的原创文章。 另外,我还在连载一套《小白白的Java自学教程》,力求通俗易懂,由浅入深。 同时,我也是一个工具爱好者,经常分享一些高效的黑科技工具和网站。

对了,公众号也分享了很多我的学习心得,大家一起讨论吧!

 
反对 0举报 0 收藏 0 打赏 0评论 0
 
更多>同类资讯
推荐图文
推荐资讯
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报
Powered By DESTOON