equals && deepEquals
equals && deepEquals
本文分为以下几个部分
equals
首先说明:这里说的 equals 是 java.util.Arrays#equals 的,不是 java.lang.Object#equals 下的。
当我们比较两个数组中的每个值是否相等时(俩数组大小是一样的情况下),经常会用循环去判断
public static void main(String[] args) {
String[] a = {"a","b"};
String[] b = {"a","b"};
int len = a.length;
boolean flag = true;
for(int i = 0; i < len; i++){
if(!a[i].equals(b[i])){
flag = false;
break;
}
}
//输出:a 和 b 数组相同
System.out.println("a 和 b 数组" + (flag ? "相同" : "不相同"));
}
实际上java提供了一种直接比较的方法 equals
public static void main(String[] args) {
String[] a = {"a","b"};
String[] b = {"a","b"};
//输出:a 和 b 数组相同
System.out.println("a 和 b 数组" + (Arrays.equals(a,b) ? "相同" : "不相同"));
}
equals的源码如下
/**
* Returns <tt>true</tt> if the two specified arrays of Objects are
* <i>equal</i> to one another. The two arrays are considered equal if
* both arrays contain the same number of elements, and all corresponding
* pairs of elements in the two arrays are equal. Two objects <tt>e1</tt>
* and <tt>e2</tt> are considered <i>equal</i> if <tt>(e1==null ? e2==null
* : e1.equals(e2))</tt>. In other words, the two arrays are equal if
* they contain the same elements in the same order. Also, two array
* references are considered equal if both are <tt>null</tt>.<p>
*
* @param a one array to be tested for equality
* @param a2 the other array to be tested for equality
* @return <tt>true</tt> if the two arrays are equal
*/
public static boolean equals(Object[] a, Object[] a2) {
//判断是否为同一个东西,即是否地址相同
if (a==a2)
return true;
//再判断 a 或者 a2 中是否有为空的情况
if (a==null || a2==null)
return false;
//判断长度
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i<length; i++) {
Object o1 = a[i];
Object o2 = a2[i];
//注意 Object 的 equals 是 ==
//比较两个值,由于不是 new 出来的,若o1、o2值相同的话,o1、o2指向的是常量池的同一个东西
if (!(o1==null ? o2==null : o1.equals(o2)))
return false;
}
return true;
}
所以以后直接调用 Arrays.equals 就可以啦,甚至都不用管里面大小啊,是否为空啊,都帮你判断好了。
我们再来试一下多维数组
public static void main(String[] args) {
String[][] a = {{"a"},{"b"}};
String[][] b = {{"a"},{"b"}};
//输出:a 和 b 数组不相同
System.out.println("a 和 b 数组" + (Arrays.equals(a,b) ? "相同" : "不相同"));
}
这次对于二维数组输出的是不相同,思考一下,进去的比较的是 {"a"}.equals{"a"} , 此时比较的是两个数组,Object的比较肯定会出现问题,那么我们修改一下,循环判断每个数组。
public static void main(String[] args) {
String[][] a = {{"a"},{"b"}};
String[][] b = {{"a"},{"b"}};
int len = a.length;
boolean flag = true;
for(int i = 0; i < len; i++){
if(!Arrays.equals(a[i],b[i])){
flag = false;
}
}
//输出:a 和 b 数组相同
System.out.println("a 和 b 数组" + (flag ? "相同" : "不相同"));
}
二维的可以循环一次,那三维的岂不是要循环两次?多维的岂不是更离谱?
Java早就想到了这个问题,所以提供了一种方法deepEquals。
deepEquals
deepEquals 深层等于,判断多维数组每个值是否相同,话不多说,看代码
public static void main(String[] args) {
String[][] a = {{"a"},{"b"}};
String[][] b = {{"a"},{"b"}};
//输出:a 和 b 数组相同
System.out.println("a 和 b 数组" + (Arrays.deepEquals(a,b) ? "相同" : "不相同"));
}
输出的是 a 和 b 相同,我们看一下源码:
/**
* Returns <tt>true</tt> if the two specified arrays are <i>deeply
* equal</i> to one another. Unlike the {@link #equals(Object[],Object[])}
* method, this method is appropriate for use with nested arrays of
* arbitrary depth.
*
* <p>Two array references are considered deeply equal if both
* are <tt>null</tt>, or if they refer to arrays that contain the same
* number of elements and all corresponding pairs of elements in the two
* arrays are deeply equal.
*
* <p>Two possibly <tt>null</tt> elements <tt>e1</tt> and <tt>e2</tt> are
* deeply equal if any of the following conditions hold:
* <ul>
* <li> <tt>e1</tt> and <tt>e2</tt> are both arrays of object reference
* types, and <tt>Arrays.deepEquals(e1, e2) would return true</tt>
* <li> <tt>e1</tt> and <tt>e2</tt> are arrays of the same primitive
* type, and the appropriate overloading of
* <tt>Arrays.equals(e1, e2)</tt> would return true.
* <li> <tt>e1 == e2</tt>
* <li> <tt>e1.equals(e2)</tt> would return true.
* </ul>
* Note that this definition permits <tt>null</tt> elements at any depth.
*
* <p>If either of the specified arrays contain themselves as elements
* either directly or indirectly through one or more levels of arrays,
* the behavior of this method is undefined.
*
* @param a1 one array to be tested for equality
* @param a2 the other array to be tested for equality
* @return <tt>true</tt> if the two arrays are equal
* @see #equals(Object[],Object[])
* @see Objects#deepEquals(Object, Object)
* @since 1.5
*/
public static boolean deepEquals(Object[] a1, Object[] a2) {
//前面判断和equals一样
if (a1 == a2)
return true;
if (a1 == null || a2==null)
return false;
int length = a1.length;
if (a2.length != length)
return false;
//循环取出,注意未使用length方法
for (int i = 0; i < length; i++) {
Object e1 = a1[i];
Object e2 = a2[i];
if (e1 == e2)
continue;
if (e1 == null)
return false;
// Figure out whether the two elements are equal
//调用 deepEquals0 方法判断是否相同
boolean eq = deepEquals0(e1, e2);
if (!eq)
return false;
}
return true;
}
static boolean deepEquals0(Object e1, Object e2) {
assert e1 != null;
boolean eq;
//多维数组递归调用,再未变成最后一层数组时,会一直调用进入第一个 if 结果中
if (e1 instanceof Object[] && e2 instanceof Object[])
eq = deepEquals ((Object[]) e1, (Object[]) e2);
else if (e1 instanceof byte[] && e2 instanceof byte[])
eq = equals((byte[]) e1, (byte[]) e2);
else if (e1 instanceof short[] && e2 instanceof short[])
eq = equals((short[]) e1, (short[]) e2);
else if (e1 instanceof int[] && e2 instanceof int[])
eq = equals((int[]) e1, (int[]) e2);
else if (e1 instanceof long[] && e2 instanceof long[])
eq = equals((long[]) e1, (long[]) e2);
else if (e1 instanceof char[] && e2 instanceof char[])
eq = equals((char[]) e1, (char[]) e2);
else if (e1 instanceof float[] && e2 instanceof float[])
eq = equals((float[]) e1, (float[]) e2);
else if (e1 instanceof double[] && e2 instanceof double[])
eq = equals((double[]) e1, (double[]) e2);
else if (e1 instanceof boolean[] && e2 instanceof boolean[])
eq = equals((boolean[]) e1, (boolean[]) e2);
else
eq = e1.equals(e2);
return eq;
}
从源码中看到,deepEquals同样可以在一维数组中使用
public static void main(String[] args) {
String[] a = {"a","b"};
String[] b = {"a","b"};
//输出:a 和 b 数组相同
System.out.println("a 和 b 数组" + (Arrays.deepEquals(a,b) ? "相同" : "不相同"));
}
总结
在一维数组中,使用 Arrays.equals 或者 Arrays.deepEquals 都可以帮你判断其中的值是否相同。
但在二维及以上,使用 Arrays.deepEquals 会比 Arrays.equals 方便(需要写递归或者循环判断,过于复杂)。
equals && deepEquals的更多相关文章
- 【Java】Objects 源码学习
2017-02-10 by 安静的下雪天 http://www.cnblogs.com/quiet-snowy-day/p/6387321.html 本篇概要 Objects 与 Object ...
- 【Java】java.util.Objects 源码学习
2017-02-10 by 安静的下雪天 http://www.cnblogs.com/quiet-snowy-day/p/6387321.html 本篇概要 Objects 与 Object ...
- JDK1.8源码(四)——java.util.Arrays类
一.概述 1.介绍 Arrays 类是 JDK1.2 提供的一个工具类,提供处理数组的各种方法,基本上都是静态方法,能直接通过类名Arrays调用. 二.类源码 1.asList()方法 将一个泛型数 ...
- Java中Arrays数组工具类的使用全解
本文几乎涵盖了所有的Arrays工具类(基于Java 11)的方法以及使用用例,一站式带你了解Arrays类的用法,希望对大家有帮助. 码字不易,三连支持一下吧 Arrays数组工具类 方法一览表 快 ...
- 《Java编程思想》学习笔记(详细)
目录 01 对象导论 02 一切都是对象 03 操作符 04 控制执行流程 05 初始化与清理 06 访问权限控制 07 复用类(继承) 08 多态 09 接口 10 内部类 11 持有对象 12 通 ...
- equals变量在前面或者在后面有什么区别吗?这是一个坑点
我就不废话那么多,直接上代码: package sf.com.mainTest; public class Test { public static void main(String[] args) ...
- How to implement equals() and hashCode() methods in Java[reproduced]
Part I:equals() (javadoc) must define an equivalence relation (it must be reflexive, symmetric, and ...
- 【特种兵系列】String中的==和equals()
1. 小样示例 public static void main(String[] args) { String a = "a" + "b" + 123; Str ...
- (转)浅谈Java中的equals和==
原文地址: http://www.cnblogs.com/dolphin0520/p/3592500.html 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new S ...
- 浅谈Java中的equals和==(转)
浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...
随机推荐
- MogDB 操作系统优化指南
MogDB 操作系统优化指南 本文出处:https://www.modb.pro/db/413280 在性能调优过程中,可以根据实际业务情况修改关键操作系统(OS)配置参数,以提升 MogDB 数据库 ...
- 历时 4 个月,CabloyJS 4.21震撼发布,应对大型项目开发
引言 凡是可以用 JavaScript 来写的应用,最终都会用 JavaScript 来写 | Atwood 定律 目前市面上出现的大多数与 NodeJS 相关的框架,基本都将 NodeJS 定位在工 ...
- oracle database recover database (下篇)
1. recover database 恢复级别一共三个:recover database > recover tablespace > recover datafile ,最高级别 da ...
- 【译】Visual Studio 中的 GitHub Copilot:2023年回顾
在快速发展的软件开发世界中,保持领先是至关重要的.在 Visual Studio 中引入AI,特别是 GitHub Copilot,已经彻底改变了开发人员的编码方式.通过将 Copilot 集成到 V ...
- 面试连环炮系列(二十️四):为什么选择RocketMQ
为什么选择RocketMQ,而不是其他MQ 性能:阿里支撑,经受住淘宝,天猫双11重重考验:性能高:可靠性好:可用性高:易扩展. 功能:功能完善,我们需要的功能基本都够满足,如:事务消息,消息重试,死 ...
- 重新点亮linux 命令树————su和sudo[七]
前言 简单整理一下su和sudo这两个命令. 正文 su 这个命令是用来切换用户的. 一般我们切换命令su,还是在原来的路径下面,但是如果想要直接回到切换用户的用户目录的话,可以使用su - user ...
- 实训篇-JavaScript-陶渊明去没去过桃花源
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 使用WebApi+Vue3从0到1搭建《权限管理系统》:二、搭建JWT系统鉴权
视频地址:[WebApi+Vue3从0到1搭建<权限管理系统>系列视频:搭建JWT系统鉴权-哔哩哔哩] https://b23.tv/R6cOcDO qq群:801913255 一.在ap ...
- ECharts海量数据渲染解决卡顿的4种方式
场景 周五进行需求评审的时候: 出现了一个图表,本身一个图表本没有什么稀奇的: 可是产品经理在图表的上的备注,让我觉得这个事情并不简单: 那个图表的时间跨度可以是月,年,而且时间间隔很短: 这让我意识 ...
- 转载 | 基于阿里云Serverless函数计算开发的疫情数据统计推送机器人
简介: 本文选自函数计算征集令优秀征文! 一.Serverless函数计算 什么是Serverless? 在<Serverless Architectures>中对 Serverless ...