多个数字数组_七个问题帮助初学者深入理解Java数组

短文涨姿势,看了不白看,不关注等啥?

几乎所有的高级语言当中,都提供了一种叫做”数组”的东西,Java语言当然也不例外。我们通过数组可以很方便的存储和管理一组数据。因为在Java语言当中使用数组非常的方便,所以导致很多初学者忽略了对数组的深入学习,本文就通过七个问题,来帮助初学者深入理解一下Java语言的数组到底是怎么回事。

一、数组是变量的简单叠加吗?

我们在学习Java的时候,知道一个int类型的变量可以存储一个整数,而一个int类想的数组可以存储多个整数。于是很多人认为数组只不过是变量的简单叠加而已,无非是变量存1个数,数组存多个数。其实不然,Java语言是把数组当作一个“对象”来看待的。我们来看下面的代码

0b51b402cf5337918fca659282552891.png

我们可以看到,在代码中声明了int型变量a和int型数组b,b的长度为1。a和b都只能存储1个int型数据,似乎它们之间没什么区别。但是请注意:a和b之间其实是有本质区别的,a是一个基础数据类型的变量,而b则是一个对象!正因为它是一个对象,所以我们才可以调用到它的getClass()方法。那么紧接着小伙伴们会问:b既然是一个对象,那么这个对象是什么类型的呢?我们可以通过“b.getClass().getName()”获得它类型的名称是” [I”。读者也可以通过这种方式,获得其他几种基础数据类型数组的类型名称。最重要的是,我们必须搞清楚:数组不是变量的简单叠加!即便是基础数据类型的数组,也是以对象的形式存在的。

二、为什么数组的下标是从0开始的?

同很多编程语言一样,Java语言数组的下标也是从0开始的。很多初学者都不理解,为什么数组下标要从0而不是从1开始?这太不符合我们的日常计数习惯了。为了说清楚这个问题,我们还是先看一段代码

f10614a7cac0b1c1e3b5bd857f4580fb.png

在这段代码中,创建了一个长度为5的数组并命名为a。在程序实际运行的时候,会分配一组连续的空间,这组空间中可以存储5个int型数据。为了能够准确的从这组空间的任意一个单元中找到数据,虚拟机必须能够对这组空间中任意一个单元做出识别。那么如何识别每个单元呢?虚拟机可以把每个单元都进行单独的命名,这样做当然能够达到目的,但是这么做跟使用变量就没什么区别了,更体现不出这组数据是一个连续的整体。实际的情况是:虚拟机给这组空间的第一个单元命名为a,如果希望找到a本身,那么就直接用a[0]来表示,其中方括号中的0表示偏移量。偏移量为0,就表示找的就是a这个空间中的数据,而a[1]表示以a为基准点,偏移1个单元,这样就找到了数组中第2个元素,以此类推,想找到数组中第5个元素,就以a这个单元为基准点,再偏移4个单元即可。因此我们就可以知道,数组的下标本质上并不是数组元素的编号,而是以数组首元素为基准点所偏移的量。这就是数组下标从0开始的原因。

三、数组的长度为什么可以用变量表示?

我们还是先来看一段代码

bab40f2732eaddf0ae237c531bbfbdb4.png

这段代码中,在创建数组的时候,以变量表示了这个数组的长度,这种做法放到Java语言中似乎很常见,但是如果使用C语言编程,在创建数组的时候,数组的长度必须是一个固定的值,不能用变量来表示。很多人似乎对这个问题不以为然,只是简单的认为这只是Java和C语言之间一点简单的语法差别而已。

其实问题远不是这么简单。这个简单的语法差别其实体现出了Java与C语言之间编译和运行机制本质的不同。变量是运行时才被赋值的,Java语言允许把数组的长度以变量的形式来表示,其背后的根本原因就是允许数组一直等到”运行时”才把长度确定下来。也就是说,程序员可以在编码的时候,不用规定数组的长度,等到程序实际运行的时候,根据实际需要去确定数组的长度,这样大大增加了程序的灵活性。

举个例子:如果我们编写程序,要求用户输入几个数字保存到数组中,然后进行排序,用户输入多少个数字不确定。如果我们用Java语言去完成这个程序,只要先让用户输入他想对多少个数字进行排序,然后把数字的个数保存到一个变量中,接着以这个变量的值作为长度创建数组就可以。但是如果是用C语言来完成程序,那么程序员必须在编写代码的时候就把数组的长度定下来,而不能等到程序运行的时候再去确定。因为C语言不能动态的在运行时确定数组的长度,必须在编译阶段就把长度确定下来。但是程序员在编码的时候并不确定用户要对多少数字完成排序,于是就只能以经验推测,创建一个他认为”足够大”的数组来存放排序的数字。如果创建的数组太大,则浪费空间,如果数组太小,则无法保存全部数字。

说了这么多,重点其实就一句话:Java语言的数组可以在”运行时”确定长度!并且这个特点大大的增加了程序的灵活性。

四、Java数组的长度可以为0吗?

这个问题很简单,只要写一段代码就可以得到答案:可以!关键问题来了:长度为0的数组不能存数据,这种数组有什么意义呢?前面说过,Java语言允许在程序运行过程中动态确定数组长度。那么我们就可以设想这样的一个场景:要求编码查询出考试总分在700分以上的学员,并且把他们的姓名存储到一个字符串数组中。假如经过查询之后,发现没有成绩在700分以上的学员,该如何表示这个查询结果呢?如果查询方法返回null来表示没有查到符合条件的数据,会对后续程序带来一定的风险,因为毕竟空对象可能会导致后面的处理代码中抛出空指针异常。而用一个长度为0的数组来表示查询结果就安全多了,仅能体现出没有查到符合条件的数据,又降低了抛出异常的风险。

五、Java语言中的数组可以扩大容量吗?

答案是不可以!因为数组一旦分配了空间之后,如果想在原来空间的基础上扩大容量,就如同是扩张地盘,势必会影响到内存中其他数据的存储,所以Java语言不允许数组扩大容量。网上有很多资料,讲解了如何扩大数组的容量,并给出了实现代码。如果你仔细去看这些代码,你会发现,这些所谓扩大数组容量的算法,其实现过程都是新创建一个更大的数组,然后把原数组中的数据拷贝到新数组中,最终返回那个新创建的数组。因此这种所谓的扩容算法其实并不是真正的扩容。

六、可以创建抽象类数组吗?

还是看代码

7cb8401ea9c9ce6e4ae8b5b6314458b1.png

代码中创建了一个抽象类A,并且在main()方法中创建了一个A类型的数组。问题又来了:抽象类A不能创建对象,而现在不仅创建了对象,并且还是一组!这是怎么回事?其实这也是很多初学者在理解引用类型数据数组的一个误区:认为数组中存放的某种类型的对象。其实不然,引用数据类型的数组中,存放的并不是对象,而只是能指向这种对象的引用而已。就拿上面这段代码来说,数组a中并没有存放5个A类型的对象,而只是存放了5个能够指向A类型对象的引用,这些引用在数组初始化的过程中,都指向空对象(null),所以千万不要错误的认为创建了某类型的数组,同时就创建了N个该类型的对象。代码中,数组a中所存放的那些引用,将来所指向的必定也是A类子类的对象,因为A类自身根本就不能创建对象。

七、多维数组的length属性值是多少?

看代码

99c4f173405b07e065afed517c04a072.png

以上代码运行,输出结果会是多少呢?一部分初学者会认为输出的结果是12,因为这个数组能够存储12个数字。但程序实际运行输出的结果却是3,这是为什么呢?就是因为,无论数组本身的维度是多少,在Java虚拟机看来,这个数组都是一维数组!有小伙伴可能不解:a明明是一个二维数组,怎么会被当作是一维数组呢?我们可以看下图来帮助理解

4070db117ee6463d55ea51bcf3a2335b.png

我们可以看到,图中是一个3行4列的二维数组。但是如果我们把数组中的每一行看作是一个元素,那么这个二维数组就可以被理解为一个一维数组,数组中包含3个元素,只不过每个元素并不是一个简单的数字,而是一个一维数组。也就是说,这个二维数组可以被理解为”由3个一维数组组成的数组”。Java语言就是以这样的方式来管理数组的,无论数组维度是多少,都被当作一维数组,如果数组中的元素又是数组(严格的表述应该是:数组元素是指向一维数组的引用),那么就形成了多维数组。因此,刚才在代码中看到的那个二维数组a,它的length属性值为3而不是12。

希望通过这七个问题,能够帮助初学者深入理解Java语言的数组。

看短文,涨姿势,如想系统学习Java编程,点击下方的“了解更多”即可,不让你进去,用QQ登录就可以啦!有问题也可以加入我的QQ群一起讨论!

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

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

相关文章

java 异常练习题1

建立exception包,建立Bank类,类中有变量double balance表示存款,Bank类的构造方法能增加存款,Bank类中有取款的发方法withDrawal(double dAmount),当取款的数额大于存款时,抛出InsufficientFundsException,取款数额为负数,抛出Nag…

大话设计模式读书笔记--6.原型模式

简单的复制粘贴极有可能造成重复代码的灾难, 但是java中提供了克隆的功能, 如果一个对象创建过程复杂,又要频繁使用, 在初始化信息不发生变化的情况下,应当采取克隆而不是new一个对象 定义 原型模式: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 也就是说,…

Java 7#8:测试台上的NIO.2文件通道

关于新JDK 7功能的另一篇博客文章。 这次我正在写有关新的AnsynchronousFileChannel类的文章。 我将在两周内深入分析新的JDK 7功能,并决定连续编号我的帖子。 只是为了确保我不会感到困惑:-)这是我关于Java 7的第七篇文章(我承认–碰巧–这也…

5页面title样式修改_认识html:实现网站页面是这么简单的一回事

互联网时代人们通过上网浏览信息,打开浏览器上网看到丰富的图文、视频、音乐等多媒体信息,一系列信息反馈和视觉冲击之后,您有没有想过,互联网这么发达的时代,您觉得花一点点时间学会做个网站页面不真香?概…

iOS指南针

前言: 这个小项目使用到了CoreLocation框架里面的设备朝向功能,对CoreLocation感兴趣的可以翻一下之前的文章 在另一个博客站有朋友发现一个尴尬的问题(图片的东西2个方向是不对的),原谅我的大意,赶时间就直…

jq的链式调用.end();

jq的链式调用.end(); 先上code <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>li{list-style: none;width: 100px;height:20px;border:1px solid #ff0000;display: …

程序如何在两个gpu卡上并行运行_深度学习分布式训练相关介绍 - Part 1 多GPU训练...

本篇文章主要是对深度学习中运用多GPU进行训练的一些基本的知识点进行的一个梳理文章中的内容都是经过认真地分析&#xff0c;并且尽量做到有所考证抛砖引玉&#xff0c;希望可以给大家有更多的启发&#xff0c;并能有所收获介绍大多数时候&#xff0c;梯度下降算法的训练需要较…

系统英伟达gpu驱动卸载_绕过CPU,英伟达让GPU直连存储设备

英伟达最近发布了一个新的GPUDirect Storage&#xff0c;暂且叫做GPU直连存储&#xff0c;让GPU直接连到NVMe存储设备上。这一方案用到了RDMA设备来把数据从闪存存储转移到GPU本地的内存里&#xff0c;无需经过CPU还有系统内存。如果这一举措顺利的话&#xff0c;英伟达就能摆脱…

嘲弄和存根–了解Mockito的测试双打

介绍 我遇到的一件事是使用模拟框架的团队假设他们在模拟。 他们并不知道Mocks只是Gerard Meszaros在xunitpatterns.com上归类的“测试双打”之一。 重要的是要意识到每种类型的测试双精度在测试中都扮演着不同的角色。 用与您需要学习不同模式或重构的方式相同&#xff0c;您…

【代码笔记】iOS-首页3张图片变化

一&#xff0c;效果图。 二&#xff0c;工程图。 三&#xff0c;代码。 RootViewController.h #import <UIKit/UIKit.h>interface RootViewController : UIViewController {NSTimer *timer;UIImageView *imageView1;UIImageView *imageView2;UIImageView *imageView3;UIV…

使用Eclipse在Amazon Ec2中部署Java Web应用程序的完整指南

嗨&#xff0c;读者们&#xff0c; 今天&#xff0c;我将向您展示如何使用Eclipse IDE在Amazon EC2中部署简单的Java Web应用程序。 在我们开始之前&#xff0c;我们需要一些必需的东西&#xff0c; Eclipse Java EE IDE –您可以从http://www.eclipse.org/downloads/下载&…

Spring 3和Java EE 6 –不公平和不完整的比较

这篇小文章的初稿标题为“ Spring&#xff06;Java EE –比较苹果和橙子”。 在撰写本文时&#xff0c;我了解到可以比较Spring Framework和Java EE&#xff0c;但这始终是不公平且不完整的工作。 Java for Enterprise和Spring Framework的发展紧密地联系在一起。 两者相互依存…

xml配置文件推荐方式

1.XML帮助类 /// <summary>/// Xml帮助类/// </summary>public class XmlHelper{/// <summary>/// 保存xml/// </summary>/// <typeparam name"T"></typeparam>/// <param name"path"></param>/// <p…

AFNetWorking https SSL认证

一般来讲如果app用了web service , 我们需要防止数据嗅探来保证数据安全.通常的做法是用ssl来连接以防止数据抓包和嗅探 其实这么做的话还是不够的 。 我们还需要防止中间人攻击&#xff08;不明白的自己去百度&#xff09;。攻击者通过伪造的ssl证书使app连接到了伪装的假冒的…

查看环境列表_Xfce 4.14桌面环境正式发布,想要图形界面又想节省内存?就它了...

1. Xfce 4.14桌面环境正式发布&#xff0c;它有什么新特性&#xff1f;本文主要讲解Xfce 4.14桌面环境正式发布&#xff0c;它有什么新特性。Xfce已经开发了4年多&#xff0c;但是这个周末终于看到了期待已久的Xfce 4.14的发布。Xfce 4.14是这个轻量级桌面环境的最新稳定版本&a…

卷积神经网络语音识别_用于物体识别的3D卷积神经网络

本文提出了一种基于CNN的3D物体识别方法&#xff0c;能够从3D图像表示中识别3D物体&#xff0c;并在比较了不同的体素时的准确性。已有文献中&#xff0c;3D CNN使用3D点云数据集或者RGBD图像来构建3D CNNs&#xff0c;但是CNN也可以用于直接识别物体体积表示的体素。本文中&am…

#获得请求来源ip_以太网数据包TCP、IP、ICMP、UDP、ARP协议头结构详解

以太网首部目地MAC地址(8字节)源MAC地址(8字节)类型(2字节)1、IP头的结构版本(4位)头长度(4位)服务类型(8位)封包总长度(16位)封包标识(16位)标志(3位)片断偏移地址(13位)存活时间(8位)协议(8位)校验和(16位)来源IP地址(32位)目的IP地址(32位)选项(可选)填充(可选)数据(1)字节和…

c# ef报错_C# EF调用MySql出现“未将对象引用设置到对象的实例”错误解决方案

C# EF调用MySql出现“未将对象引用设置到对象的实例”错误解决方案---修改步骤---1.打开Nuget管理包&#xff0c;把Mysql.Data替换为6.10.0以下任意版本。这里选择的是6.8.82.修改完毕后&#xff0c;继续把Mysql.Data.Entity也修改为对应版本6.8.8。3.安装完成后可以看到App.Co…

ServletRequest startAsync()的有用性有限

前段时间我遇到了Servlet 3.0中AsyncContext.start&#xff08;…&#xff09;的目的是什么&#xff1f; 题。 引用上述方法的Javadoc &#xff1a; 使容器调度线程&#xff08;可能从托管线程池中&#xff09;运行指定的Runnable 。 提醒大家&#xff0c; AsyncContext是Servl…

mysql所支持的比较运算符_mysql比较运算符有哪些?Mysql比较运算符详解

比较运算符可用于比较数字和字符串。今天发一篇Mysql比较运算符详解&#xff0c;希望对初学者有所帮助&#xff0c;虽然现在流行NoSQL&#xff0c;但是MYSQL还是很有用的&#xff0c;数字作为浮点值进行比较&#xff0c;字符串以不区为例进行比较&#xff0c;运算符用于比较表达…