Java开发笔记(二十三)数组工具Arrays
数组作为一种组合形式的数据类型,必然要求提供一些处理数组的简便办法,包括数组比较、数组复制、数组排序等等。为此Java专门设计了Arrays工具,该工具包含了几个常用方法,方便程序员对数组进行加工操作。Arrays工具的方法说明如下:
Arrays.equals(a1, a2); // 判断a1和a2两个数组是否相等,也就是每个元素是否都相等
Arrays.fill(a, val); // 往数组a全部填入指定的数值val
dest = Arrays.copyOf(src, newLength); // 把数组src的内容赋值给数组dest,且dest的长度为newLength
Arrays.sort(a); // 对数组a的内部元素进行排序,结果是按照升序排序
下面分别对以上的四个数组处理方法进行介绍:
1、Arrays.equals方法
前面说过,双等号“==”可用来判断两个变量的数值是否相等,但“==”只适合基本变量类型之间的比较,例如比较两个整型变量是否相等、两个双精度数是否相等、两个布尔变量是否相等。如果两个数组变量通过“==”进行相等判断,则比较的是这两个数组是否为同一个数组,而不是比较两个数组的所有元素是否都相等。要想判断两个数组内部的每个元素是否一一相等,就必须通过Arrays工具的equals方法来辨别。equals方法返回true表示两个数组的所有元素都相等,返回false表示两个数组至少有一个元素不相等。
2、Arrays.fill方法
在声明数组变量的时候,经常需要对它进行初始化赋值,比如书店进了十本书,每本书的售价都是99元,那么按照常规写法只能书写十遍99,就像下面代码这样:
// 构造一个包含十个99的数组变量
int[] prices = {99, 99, 99, 99, 99, 99, 99, 99, 99, 99};
显然输入重复的数字是个负担,尤其重复数量很多的时候更甚。现在利用Arrays的fill方法,只需一行代码即可对该数组的所有元素都填上相同的数值,于是数组的初始赋值代码便优化为下面这样:
// 声明一个整型数组,数组大小为10
int[] prices = new int[10];
// 给整型数组的每个元素全部填写99
Arrays.fill(prices, 99);
// 打印整型数组的所有元素数值
for (int price : prices) {
System.out.println("price = "+price);
}
3、Arrays.copyOf方法
把一个数组变量赋值给另一个数组变量,似乎可以用等号直接赋值,这种情况在一般情况下没有问题。但若是赋值之后修改了原数组的某个元素,那就出现问题了。譬如以下的演示代码,先把数组变量pricesOrigin赋值给pricesAssign,接着修改原数组pricesOrigin的元素值,再去打印新数组pricesAssign的所有元素:
// 声明一个整型数组,数组大小为5,并且5个元素全为99
int[] pricesOrigin = {99, 99, 99, 99, 99};
// 复制数组的第一个办法:利用等号直接赋值
int[] pricesAssign = pricesOrigin;
pricesOrigin[1] = 80;
for (int price : pricesAssign) {
System.out.println("assign price = "+price);
}
运行以上的演示代码,完整的日志输出如下所示:
assign price = 99
assign price = 80
assign price = 99
assign price = 99
assign price = 99
没想到打印出来的第二个数组元素竟然变了,可是演示代码明明只改了原数组pricesOrigin,并未修改新数组pricesAssign呀。让测试程序出现神经错乱的缘故,乃是数组之间的等号赋值相当于给数组起个别名,并非从头到尾完整复制一个新数组出来。既然只是起了个别的名称,那么实际上还是原名称所指的数组,无非是该数组有两个姓名罢了。
显然这个情况不是程序员期望的结果,程序员的本意是复制另外的数组,新数组不再与原数组有任何关联,大家井水不犯河水,互不干涉、互不影响。最好克隆一个一模一样的新数组出来,Java恰巧给每个数组变量都提供了clone方法,该方法正是拿来克隆数组用的。克隆出来的新数组有分配单独的存储空间,并且数组元素的数值与原数组完全一致,如此便实现了正常意义上的数组赋值功能。利用clone方法复制数组变量的示例代码如下:
// 复制数组的第二个办法:调用原数组的clone方法
int[] pricesClone = pricesOrigin.clone();
pricesOrigin[1] = 80;
for (int price : pricesClone) {
System.out.println("clone price = "+price);
}
运行如上的示例代码,得到下面的日志输出结果:
clone price = 99
clone price = 99
clone price = 99
clone price = 99
clone price = 99
可见此时修改了原数组的元素数值,并没有改变新数组的元素值,真正做到了完整的复制操作。
不过clone方法人如其名,它把原数组的所有元素一个不漏全部复制到新数组,这意味着,如果只想复制部分元素给新数组,那末clone方法就无能为力了。为此,Java给Arrays工具增配了一个copyOf方法,该方法允许从来源数组复制若干元素给目标数组。当待复制的元素个数恰好等于原数组的大小时,copyOf方法的作用等同于数组变量的clone方法。下面是通过copyOf方法将数组原样复制到新数组的代码例子:
// 复制数组的第三个办法:调用Arrays工具的copyOf方法
int[] pricesCopy = Arrays.copyOf(pricesOrigin, pricesOrigin.length);
pricesOrigin[1] = 80;
for (int price : pricesCopy) {
System.out.println("copy price = "+price);
}
从上面代码看到,copyOf方法身后跟着两个参数,第一个参数是原数组的名称,第二个参数是要复制的元素个数。接下来把第二个参数改小一点,看看copyOf方法是否真的支持只复制部分元素?于是第二个参数改为“pricesOrigin.length-1”之后的代码如下所示:
// 改变copyOf方法的第二个参数值,允许复制指定大小的数组元素
int[] pricesPart = Arrays.copyOf(pricesOrigin, pricesOrigin.length-1);
for (int price : pricesPart) {
System.out.println("part price = "+price);
}
重新运行修改后的数组复制代码,日志输出结果见下:
part price = 99
part price = 99
part price = 99
part price = 99
这下看到新数组的元素只有四个,而原数组共有五个元素,说明此时的确只复制了部分元素。
Arrays工具的copyOf方法还有个妙用,比如有个数组分配了初始大小为5,现在想把该数组的长度扩大到10,这时利用copyOf方法就能动态调整数组的大小。具体做法是:调用copyOf方法之时,来源数组和目标数组都填该数组的名称,然后待复制的元素大小填写扩大后的长度。下面的代码便演示了如何将某数组的大小拉长一位:
// 把copyOf方法的返回值赋给原数组,可以动态调整该数组的大小
pricesOrigin = Arrays.copyOf(pricesOrigin, pricesOrigin.length+1);
for (int price : pricesOrigin) {
System.out.println("origin price = "+price);
}
运行调整数组大小的演示代码,观察到以下的日志输出:
origin price = 99
origin price = 99
origin price = 99
origin price = 99
origin price = 99
origin price = 0
由此可见,数组大小果然增大了一位,并且新增的数组元素值为0,这正是整型变量的默认数值。
4、Arrays.sort方法
顾名思义,Arrays工具的sort方法是给数组元素排序的,并且排序结果为升序。sort方法用起来很简单,只要把待排序的数组名称填进圆括号,编译器就会自动完成该数组的排序任务。举个给整型数组排序的例子,简单的Java实现代码如下:
int[] pricesOrigin = {99, 80, 18, 68, 8};
// 对整型数组pricesOrigin里的元素进行排序操作,sort方法得到的结果是升序排列
Arrays.sort(pricesOrigin);
for (int price : pricesOrigin) {
System.out.println("origin price = "+price);
}
运行上述的排序代码,得到下面的结果日志:
origin price = 8
origin price = 18
origin price = 68
origin price = 80
origin price = 99
从日志看到,排序后的数组元素从小到大打印,很明显这是升序排列。
当然,在前面的例子中,数组元素早在声明数组时便初始化赋值了,实战性不强。接下来尝试动态生成一个随机数数组,再对该数组进行排序,这样更贴近实际业务。详细的实现代码可能涉及到数组、循环、冒号跳转等技术,有兴趣的朋友不妨动手实践。下面是随机数组生成并排序的代码例子:
int[] numbers = new int[20];
loop : for (int i=0; i<numbers.length; i++) {
// 生成一个小于100的随机整数
int item = (int) Math.round(Math.random()*1000%100);
// 下面的循环用来检查数组中是否已经存在该随机数
for (int j=0; j<i; j++) {
if (numbers[j] == item) {
i--;
// 已经存在该随机数,则继续第一层循环,重新生成随机数
continue loop;
}
}
// 原数组不存在该随机数,则把随机数加入到数组中
numbers[i] = item;
}
// 对整型数组numbers里的元素进行排序操作,sort方法得到的结果是升序排列
Arrays.sort(numbers);
for (int number : numbers) {
System.out.println("number = "+number);
}
更多Java技术文章参见《Java开发笔记(序)章节目录》
Java开发笔记(二十三)数组工具Arrays的更多相关文章
- Java开发笔记(十三)利用关系运算符比较大小
前面在<Java开发笔记(九)赋值运算符及其演化>中提到,Java编程中的等号“=”表示赋值操作,并非数学上的等式涵义.Java通过等式符号“==”表示左右两边相等,对应数学的等号“=”: ...
- Java 学习笔记 二维数组和对象数组
定义二维数组 int[][] a = new int[4][5]; 可以不指定列数 int[][] a = new int[4][]; 获取行 int i = a.length(); 如果使用第一个例 ...
- Java开发学习(二十三)----SpringMVC入门案例、工作流程解析及设置bean加载控制
一.SpringMVC概述 SpringMVC是隶属于Spring框架的一部分,主要是用来进行Web开发,是对Servlet进行了封装.SpringMVC是处于Web层的框架,所以其主要的作用就是用来 ...
- Java学习笔记二十三:Java的继承初始化顺序
Java的继承初始化顺序 当使用继承这个特性时,程序是如何执行的: 继承的初始化顺序 1.初始化父类再初始子类 2.先执行初始化对象中属性,再执行构造方法中的初始化 当使用继承这个特性时,程序是如何执 ...
- Java开发笔记(序)章节目录
现将本博客的Java学习文章整理成以下笔记目录,方便查阅. 第一章 初识JavaJava开发笔记(一)第一个Java程序Java开发笔记(二)Java工程的帝国区划Java开发笔记(三)Java帝国的 ...
- Java开发学习(二十五)----使用PostMan完成不同类型参数传递
一.请求参数 请求路径设置好后,只要确保页面发送请求地址和后台Controller类中配置的路径一致,就可以接收到前端的请求,接收到请求后,如何接收页面传递的参数? 关于请求参数的传递与接收是和请求方 ...
- Java开发学习(二十四)----SpringMVC设置请求映射路径
一.环境准备 创建一个Web的Maven项目 参考Java开发学习(二十三)----SpringMVC入门案例.工作流程解析及设置bean加载控制中环境准备 pom.xml添加Spring依赖 < ...
- Java开发学习(二十六)----SpringMVC返回响应结果
SpringMVC接收到请求和数据后,进行了一些处理,当然这个处理可以是转发给Service,Service层再调用Dao层完成的,不管怎样,处理完以后,都需要将结果告知给用户. 比如:根据用户ID查 ...
- Java开发学习(二十七)----SpringMVC之Rest风格解析及快速开发
一.REST简介 REST(Representational State Transfer),表现形式状态转换,它是一种软件架构风格 当我们想表示一个网络资源的时候,可以使用两种方式: 传统风格资源描 ...
- Java开发学习(二十八)----拦截器(Interceptor)详细解析
一.拦截器概念 讲解拦截器的概念之前,我们先看一张图: (1)浏览器发送一个请求会先到Tomcat的web服务器 (2)Tomcat服务器接收到请求以后,会去判断请求的是静态资源还是动态资源 (3)如 ...
随机推荐
- koa 写简单服务
这两天用koa写了点服务,这里面和express还是有部分区别的 1.静态服务: koa 中,是有中间件, koa-static, const static_f = require('koa-sta ...
- LoadRunner(二)——性能测试过程概述
参考学习感谢:<精通软件性能测试与LoadRunner实战> 性能测试过程概述 2.1 性能测试的基本过程 2.2 性能测试需求分析 2.3 性能测试计划 2.4 性能测试用例 2.5 测 ...
- Senparc之OAuth原理
今天学习了网易云课堂的 盛派的微信开发课程之OAuth微信网页授权:OAuth原理,边听边来波笔记: 1.什么是OAuth? OAuth 你的接口提供给别人使用,你需要提供Oauth,可以让被人使用, ...
- C语言面试题分类->字符串处理
1.strlen:计算字符串长度(不包含'\0') 实现想法:遍历字符串,直到'\0'结束 #include<stdio.h> #include<stdlib.h> #incl ...
- CMS使用对应版本当作新项目。
document.form1 整体替换document.forms[0] document.Templetslist 整体替换document.forms[0] document.f_Upload整体 ...
- 【安富莱专题教程第3期】开发板搭建Web服务器,利用花生壳让电脑和手机可以外网远程监控
说明:1. 开发板Web服务器的设计可以看我们之前发布的史诗级网络教程:链接.2. 需要复杂些的Web设计模板,可以使用我们V6开发板发布的综合Demo:链接.3. 教程中使用的是花生壳免费版, ...
- Oracle客户端、服务的安装及干净卸载Oracle
软件下载地址: 链接:https://pan.baidu.com/s/1Sluf890eNuaV8muL55eO2w 提取码:oez7 服务端因文件过大,所以分了两个文件压缩包,下载后将内容解压后放置 ...
- [Swift]LeetCode414. 第三大的数 | Third Maximum Number
Given a non-empty array of integers, return the third maximum number in this array. If it does not e ...
- [Swift]LeetCode731. 我的日程安排表 II | My Calendar II
Implement a MyCalendarTwoclass to store your events. A new event can be added if adding the event wi ...
- 10 个深恶痛绝的 Java 异常。。
异常是 Java 程序中经常遇到的问题,我想每一个 Java 程序员都讨厌异常,一 个异常就是一个 BUG,就要花很多时间来定位异常问题. 什么是异常及异常的分类请看这篇文章:一张图搞清楚 Java ...