java声明和初始化数组_Java 中初始化数组

9d7320fcbe48f6d9fdceb06c34fb8269.png
数组是一种有用的数据类型,用于管理在连续内存位置中建模最好的集合元素。下面是如何有效地使用它们。
-- Chris Hermansen(作者)

有使用 C 或者 FORTRAN 语言编程经验的人会对数组的概念很熟悉。它们基本上是一个连续的内存块,其中每个位置都是某种数据类型:整型、浮点型或者诸如此类的数据类型。

Java 的情况与此类似,但是有一些额外的问题。

一个数组的示例

让我们在 Java 中创建一个长度为 10 的整型数组:

int[] ia = new int[10];

上面的代码片段会发生什么?从左到右依次是:

  1. 最左边的 int[] 将变量的类型声明为 int 数组(由 [] 表示)。
  2. 它的右边是变量的名称,当前为 ia
  3. 接下来,= 告诉我们,左侧定义的变量赋值为右侧的内容。
  4. = 的右侧,我们看到了 new,它在 Java 中表示一个对象正在被初始化中,这意味着已为其分配存储空间并调用了其构造函数(请参见此处以获取更多信息)。
  5. 然后,我们看到 int[10],它告诉我们正在初始化的这个对象是包含 10 个整型的数组。

因为 Java 是强类型的,所以变量 ia 的类型必须跟 = 右侧表达式的类型兼容。

初始化示例数组

让我们把这个简单的数组放在一段代码中,并尝试运行一下。将以下内容保存到一个名为 Test1.java 的文件中,使用 javac 编译,使用 java 运行(当然是在终端中):

import java.lang.*;public class Test1 {public static void main(String[] args) {int[] ia = new int[10];                              // 见下文注 1System.out.println("ia is " + ia.getClass());        // 见下文注 2for (int i = 0; i < ia.length; i++)                  // 见下文注 3System.out.println("ia[" + i + "] = " + ia[i]);  // 见下文注 4}}

让我们来看看最重要的部分。

  1. 我们声明和初始化了长度为 10 的整型数组,即 ia,这显而易见。
  2. 在下面的行中,我们看到表达式 ia.getClass()。没错,ia 是属于一个对象,这行代码将告诉我们是哪个类。
  3. 在紧接的下一行中,我们看到了一个循环 for (int i = 0; i < ia.length; i++),它定义了一个循环索引变量 i,该变量遍历了从 0 到比 ia.length 小 1 的序列,这个表达式告诉我们在数组 ia 中定义了多少个元素。
  4. 接下来,循环体打印出 ia 的每个元素的值。

当这个程序编译和运行时,它产生以下结果:

me@mydesktop:~/Java$ javac Test1.java
me@mydesktop:~/Java$ java Test1
ia is class [I
ia[0] = 0
ia[1] = 0
ia[2] = 0
ia[3] = 0
ia[4] = 0
ia[5] = 0
ia[6] = 0
ia[7] = 0
ia[8] = 0
ia[9] = 0
me@mydesktop:~/Java$

ia.getClass() 的输出的字符串表示形式是 [I,它是“整数数组”的简写。与 C 语言类似,Java 数组以第 0 个元素开始,扩展到第 <数组大小> - 1 个元素。如上所见,我们可以看到数组 ia 的每个元素都(似乎由数组构造函数)设置为零。

所以,就这些吗?声明类型,使用适当的初始化器,就完成了吗?

好吧,并没有。在 Java 中有许多其它方法来初始化数组。

为什么我要初始化一个数组,有其它方式吗?

像所有好的问题一样,这个问题的答案是“视情况而定”。在这种情况下,答案取决于初始化后我们希望对数组做什么。

在某些情况下,数组自然会作为一种累加器出现。例如,假设我们正在编程实现计算小型办公室中一组电话分机接收和拨打的电话数量。一共有 8 个分机,编号为 1 到 8,加上话务员的分机,编号为 0。 因此,我们可以声明两个数组:

int[] callsMade;
int[] callsReceived;

然后,每当我们开始一个新的累计呼叫统计数据的周期时,我们就将每个数组初始化为:

callsMade = new int[9];
callsReceived = new int[9];

在每个累计通话统计数据的最后阶段,我们可以打印出统计数据。粗略地说,我们可能会看到:

import java.lang.*;
import java.io.*;public class Test2 {public static void main(String[] args) {int[] callsMade;int[] callsReceived;// 初始化呼叫计数器callsMade = new int[9];callsReceived = new int[9];// 处理呼叫……//   分机拨打电话:callsMade[ext]++//   分机接听电话:callsReceived[ext]++// 汇总通话统计System.out.printf("%3s%25s%25sn", "ext", " calls made","calls received");for (int ext = 0; ext < callsMade.length; ext++) {System.out.printf("%3d%25d%25dn", ext,callsMade[ext], callsReceived[ext]);}}}

这会产生这样的输出:

me@mydesktop:~/Java$ javac Test2.java
me@mydesktop:~/Java$ java Test2
ext               calls made           calls received0                        0                        01                        0                        02                        0                        03                        0                        04                        0                        05                        0                        06                        0                        07                        0                        08                        0                        0
me@mydesktop:~/Java$

看来这一天呼叫中心不是很忙。

在上面的累加器示例中,我们看到由数组初始化程序设置的零起始值可以满足我们的需求。但是在其它情况下,这个起始值可能不是正确的选择。

例如,在某些几何计算中,我们可能需要将二维数组初始化为单位矩阵(除沿主对角线———左上角到右下角——以外所有全是零)。我们可以选择这样做:

double[][] m = new double[3][3];
for (int d = 0; d < 3; d++) {m[d][d] = 1.0;
}

在这种情况下,我们依靠数组初始化器 new double[3][3] 将数组设置为零,然后使用循环将主对角线上的元素设置为 1。在这种简单情况下,我们可以使用 Java 提供的快捷方式:

double[][] m = {{1.0, 0.0, 0.0},{0.0, 1.0, 0.0},{0.0, 0.0, 1.0}};

这种可视结构特别适用于这种应用程序,在这种应用程序中,它便于复查数组的实际布局。但是在这种情况下,行数和列数只在运行时确定时,我们可能会看到这样的东西:

int nrc;
// 一些代码确定行数和列数 = nrc
double[][] m = new double[nrc][nrc];
for (int d = 0; d < nrc; d++) {m[d][d] = 1.0;
}

值得一提的是,Java 中的二维数组实际上是数组的数组,没有什么能阻止无畏的程序员让这些第二层数组中的每个数组的长度都不同。也就是说,下面这样的事情是完全合法的:

int [][] differentLengthRows = {{1, 2, 3, 4, 5},{6, 7, 8, 9},{10, 11, 12},{13, 14},{15}};

在涉及不规则形状矩阵的各种线性代数应用中,可以应用这种类型的结构(有关更多信息,请参见此 Wikipedia 文章)。除此之外,既然我们了解到二维数组实际上是数组的数组,那么以下内容也就不足为奇了:

differentLengthRows.length

可以告诉我们二维数组 differentLengthRows 的行数,并且:

differentLengthRows[i].length

告诉我们 differentLengthRowsi 行的列数。

深入理解数组

考虑到在运行时确定数组大小的想法,我们看到数组在实例化之前仍需要我们知道该大小。但是,如果在处理完所有数据之前我们不知道大小怎么办?这是否意味着我们必须先处理一次以找出数组的大小,然后再次处理?这可能很难做到,尤其是如果我们只有一次机会使用数据时。

Java 集合框架很好地解决了这个问题。提供的其中一项是 ArrayList 类,它类似于数组,但可以动态扩展。为了演示 ArrayList 的工作原理,让我们创建一个 ArrayList 对象并将其初始化为前 20 个斐波那契数字:

import java.lang.*;
import java.util.*;public class Test3 {public static void main(String[] args) {ArrayList<Integer> fibos = new ArrayList<Integer>();fibos.add(0);fibos.add(1);for (int i = 2; i < 20; i++) {fibos.add(fibos.get(i - 1) + fibos.get(i - 2));}for (int i = 0; i < fibos.size(); i++) {System.out.println("fibonacci " + i + " = " + fibos.get(i));}}
}

上面的代码中,我们看到:

  • 用于存储多个 IntegerArrayList 的声明和实例化。
  • 使用 add() 附加到 ArrayList 实例。
  • 使用 get() 通过索引号检索元素。
  • 使用 size() 来确定 ArrayList 实例中已经有多少个元素。

这里没有展示 put() 方法,它的作用是将一个值放在给定的索引号上。

该程序的输出为:

fibonacci 0 = 0
fibonacci 1 = 1
fibonacci 2 = 1
fibonacci 3 = 2
fibonacci 4 = 3
fibonacci 5 = 5
fibonacci 6 = 8
fibonacci 7 = 13
fibonacci 8 = 21
fibonacci 9 = 34
fibonacci 10 = 55
fibonacci 11 = 89
fibonacci 12 = 144
fibonacci 13 = 233
fibonacci 14 = 377
fibonacci 15 = 610
fibonacci 16 = 987
fibonacci 17 = 1597
fibonacci 18 = 2584
fibonacci 19 = 4181

ArrayList 实例也可以通过其它方式初始化。例如,可以给 ArrayList 构造器提供一个数组,或者在编译过程中知道初始元素时也可以使用 List.of()array.aslist() 方法。我发现自己并不经常使用这些方式,因为我对 ArrayList 的主要用途是当我只想读取一次数据时。

此外,对于那些喜欢在加载数据后使用数组的人,可以使用 ArrayListtoArray() 方法将其实例转换为数组;或者,在初始化 ArrayList 实例之后,返回到当前数组本身。

Java 集合框架提供了另一种类似数组的数据结构,称为 Map(映射)。我所说的“类似数组”是指 Map 定义了一个对象集合,它的值可以通过一个键来设置或检索,但与数组(或 ArrayList)不同,这个键不需要是整型数;它可以是 String 或任何其它复杂对象。

例如,我们可以创建一个 Map,其键为 String,其值为 Integer 类型,如下:

Map<String, Integer> stoi = new Map<String, Integer>();

然后我们可以对这个 Map 进行如下初始化:

stoi.set("one",1);
stoi.set("two",2);
stoi.set("three",3);

等类似操作。稍后,当我们想要知道 "three" 的数值时,我们可以通过下面的方式将其检索出来:

stoi.get("three");

在我的认知中,Map 对于将第三方数据集中出现的字符串转换为我的数据集中的一致代码值非常有用。作为数据转换管道的一部分,我经常会构建一个小型的独立程序,用作在处理数据之前清理数据;为此,我几乎总是会使用一个或多个 Map

值得一提的是,ArrayListArrayListMapMap 是很可能的,有时也是合理的。例如,假设我们在看树,我们对按树种和年龄范围累计树的数目感兴趣。假设年龄范围定义是一组字符串值(“young”、“mid”、“mature” 和 “old”),物种是 “Douglas fir”、“western red cedar” 等字符串值,那么我们可以将这个 Map 中的 Map 定义为:

Map<String, Map<String, Integer>> counter = new Map<String, Map<String, Integer>>();

这里需要注意的一件事是,以上内容仅为 Map创建存储。因此,我们的累加代码可能类似于:

// 假设我们已经知道了物种和年龄范围
if (!counter.containsKey(species)) {counter.put(species,new Map<String, Integer>());
}
if (!counter.get(species).containsKey(ageRange)) {counter.get(species).put(ageRange,0);
}

此时,我们可以这样开始累加:

counter.get(species).put(ageRange, counter.get(species).get(ageRange) + 1);

最后,值得一提的是(Java 8 中的新特性)Streams 还可以用来初始化数组、ArrayList 实例和 Map 实例。关于此特性的详细讨论可以在此处和此处中找到。


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

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

相关文章

Java第二次实验报告——Java面向对象程序设计

北京电子科技学院&#xff08;BESTI&#xff09;实 验 报 告课程名称&#xff1a;java程序设计实验 班级&#xff1a;1352 姓名&#xff1a;洪韶武 学号&#xff1a;20135219成绩&#xff1a; 指导教师&#xff1a;娄嘉鹏…

IOS 多线程04-GCD详解 底层并发 API

IOS 多线程04-GCD详解 底层并发 API 注&#xff1a;本人是翻译过来&#xff0c;并且加上本人的一点见解。 前言 想要揭示出表面之下深层次的一些可利用的方面。这些底层的 API 提供了大量的灵活性&#xff0c;随之而来的是大量的复杂度和更多的责任。在我们的文章常见的后台实践…

类初始化的一道面试题

下面的代码counter1,counter2输出的结果是什么&#xff0c;把第10行放到12行后面&#xff0c;ounter1,counter2输出的结果是什么&#xff1f; 为什么&#xff1f; 1 public class Test {2 public static void main(String[] args) {3 System.out.println(Singleton…

mac pandas文件路径_Mac进阶必看:如何利用Automator快速获取文件路径

在重装mac os系统后&#xff0c;有的小伙伴会选择手动恢复数据&#xff0c;但是却发现一些软件比如FTP、iterm2、foxmail等这些软件的配置信息没有了&#xff0c;其实数据并没有丢失哦&#xff01;一般情形下数据都会在/Users/dcm/Library下&#xff0c;但是Mac默认是不显示这些…

深入分析Spring 与 Spring MVC容器

spring官方文档中对web容器的说明spring配置文件默认名字——applicationContext.xml参考链接&#xff1a;https://www.cnblogs.com/hujunzheng/p/5673377.htmlSpring的启动过程&#xff1a;首先&#xff0c;对于一个web应用&#xff0c;其部署在web容器中&#xff0c;web容器提…

mysql jpa 批注 视图_通过JPA注解映射视图的实体类 jpa 视图 无主键 @Query注解的用法(Spring Data JPA) jpa 使用sql语句...

参考: https://blog.csdn.net/qq465235530/article/details/68064074https://www.cnblogs.com/zj0208/p/6008627.html这里主要说一下怎么用jpa映射一个视图的实体类&#xff0c;其实跟表映射一样&#xff0c;就是需要添加一个空的主键id标识package com.cf.bus.core.rs.templat…

笨办法学C 练习45:一个简单的TCP/IP客户端

练习45&#xff1a;一个简单的TCP/IP客户端 原文&#xff1a;Exercise 45: A Simple TCP/IP Client 译者&#xff1a;飞龙 我打算使用RingBuffer来创建一个非常简单的小型网络测试工具&#xff0c;叫做netclient。为此我需要向Makefile添加一些工具&#xff0c;来处理bin/目录下…

Cppunit 源码 SynchronizedObject

运用C的构造&#xff0c;析构进行&#xff0c;加锁解锁。在函数进入的时候定义临时变量。任何一个分支推出的时候都会调用析构函数。避免多分支出现的问题。 1 #ifndef CPPUNIT_SYNCHRONIZEDOBJECT_H2 #define CPPUNIT_SYNCHRONIZEDOBJECT_H3 4 #include <cppunit/Portabil…

hive安装需要安装mysql区别_HIVE安装系列之一:在Linux中安装mysql,为其作为hive的metastore做准备...

安装mysql的Linux机器是Centos6的系统&#xff0c;机器名字叫combanc05mysql我采用的是5.5版本。安装过程中需要解决新旧版的冲突问题&#xff0c;并允许mysql被远程访问。以便其作为hive的元数据仓库顺利运行。下载到mysql在linux中安装mysql&#xff0c;首先可以到官网去找Li…

数据预处理和特征工程

一、数据预处理 1.数据采集 2.数据格式化&#xff08;存储格式等&#xff09; 3.数据清洗&#xff1a;去掉脏数据 简单直观可以看出的不可能数据 组合或统计属性判定 缺失值处理 1.删除元祖&#xff1a;删除这一条记录或者一列特征&#xff0c;适合记录或者特征占总样本比例很小…

个人作业五:四则运算二

四则运算2 一、设计思路&#xff1a; 1、题目避免重复&#xff1a; (1)利用系统时间来产生随机数&#xff0c;重复率会降低。 (2)建立链表&#xff0c;逐个判断。可读取写入文件。 2、可定制&#xff08;数量/打印方式&#xff09;&#xff1a; (1)格式有默认值; (2)可以选择重…

javascript继承模式原理与示例深入剖析

原型链ECMAScript 中描述了原型链的概念&#xff0c;并将原型链作为实现继承的主要方法。 其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。简单回顾一下构造函数、原型和实例的关系&#xff1a;每个构造函数都有一个原型对象&#xff0c;原型对象都包含一…

mysql innodb_sort_buffer_size_mysql优化---第7篇:参数 innodb_buffer_pool_instances设置

摘要&#xff1a;1 innodb_buffer_pool_instances可以开启多个内存缓冲池&#xff0c;把需要缓冲的数据hash到不同的缓冲池中&#xff0c;这样可以并行的内存读写。2 innodb_buffer_pool_instances参数显著的影响测试结果&#xff0c;特别是非常高的 I/O 负载时。3 实验环境下&…

函数和过程

函数&#xff1a;def test(s)&#xff1a; ... return 过程没有return&#xff0c;函数有。但是过程也是函数 def test0():过程msgi am houndprint(msg) def test1():函数msgi am dogprint(msg)return msg t1test0() t2test1() print(t1) print(t2) i am houndi am dogNone 没…

关于html的一些杂技

html预定义字符指的是 :< > html实体指的是 $amp 等 php中htmlspeciachar()就是讲html预定义字符转换成html实体. 浏览器渲染时,会将html实体转换成html预定义字符显示出来,但是查看html源码是显示的还是html实体. 而如果查看源码时(ctrlu),中<>的内容不会再网页…

cordova 5.0版本说明

2015/04/21发布Cordova 5.0.0! 1&#xff09;插件从Cordova plugins registry&#xff08;CPR&#xff09;全部移到npm&#xff0c;并且重新命名 ***org.apache.cordova.* → cordova-plugin-* 旧&#xff09;$ cordova plugin add org.apache.cordova.console 新&#xff09…

mysql综合查询索引优化_MySQL数据库SQL优化之确定问题使用索引提高查询效率

在EXPLAIN分析SQL中&#xff0c;已经可以确定是对客户表customet的全表扫描导致效率的不理想&#xff0c;那么对客户表customer的email字段创建索引&#xff0c;具体如下:mysql> create index idx_email on customer(email);创建索引后&#xff0c;再看一下这条语句的执行计…

无法找到python第三方库的处理方法

如果工程目录和python安装目录不是同一个&#xff0c;那么要将第三方库复制一份到你的工程目录的site-package目录中&#xff0c;这样工程才能引用。反正我是这样的&#xff0c;大家如果遇到类似情况可以参考。 我也在纳闷&#xff0c;像c#这些你在引用第三方库时自动就给你复制…

python-列表

list列表是一个有序的集合&#xff0c;可以随时添加和删除 len(XXX)函数计算XXX这个列表元素个数 还有一个概念就是索引index xxx(2) xxx列表的第三个元素 xxx(-2) xxx列表的倒数第二个元素 append 添加元素到末尾 insert 插入元素到指定的位置 pop()  删除末尾的元素…

201. Bitwise AND of Numbers Range

题目&#xff1a; Given a range [m, n] where 0 < m < n < 2147483647, return the bitwise AND of all numbers in this range, inclusive. For example, given the range [5, 7], you should return 4. 链接&#xff1a; http://leetcode.com/problemset/algorithm…