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 ...
随机推荐
- keystore 生成密钥
前言 在安卓中,我们需要生存keystore来处理我们的证书: 我们很幸运在keystore中,在java中的bin下,已经有了keytool工具了,感谢java社区工作者. 正文 在命令窗口中使用k ...
- dojo\dart脚本编程语言
Dojo是一个用于构建高效.可扩展的Web应用程序的开源JavaScript框架.它提供了一系列功能丰富的模块和组件,包括DOM操作.事件处理.异步编程.动画效果等.Dojo还具有强大的用户界面(UI ...
- 力扣1097(MySQL)-游戏玩法分析Ⅴ(困难)
题目: 我们将玩家的安装日期定义为该玩家的第一个登录日. 我们还将某个日期 X 的第 1 天留存时间定义为安装日期为 X 的玩家的数量,他们在 X 之后的一天重新登录,除以安装日期为 X 的玩家的数量 ...
- HarmonyOS NEXT应用开发—听歌识曲水波纹特效案例
介绍 在很多应用中,会出现点击按钮出现水波纹的特效. 效果图预览 使用说明 进入页面,点击按钮,触发水波纹动画. 再次点击按钮,停止水波纹动画. 实现思路 本例涉及的关键特性和实现方案如下: 要实现存 ...
- DevOps 能力提升模型
简介: DevOps 能力反映的是技术研发响应业务变化的能力.随着组织规模的增加和业务复杂性增长,DevOps 能力会变得越来越重要.持续提升 DevOps 的能力成为技术研发的共同挑战. 编者按:本 ...
- [Kali] Kali Linux 环境准备
虚拟机和系统: Mac 的 Vmware Fusion:https://www.vmware.com/cn/products/fusion/fusion-evaluation.html 序列号去 ...
- [Trading] 什么是交易中的顺势和逆势
开仓后的头寸开始盈利了并不断增加,这就是顺势:开仓后的头寸没有盈利或者亏损了,这就是逆势. 开仓后,用你持有的头寸判断,有浮盈的头寸单子就是正确的. 盈利取决你处理单子的能力,而处理单子是从开仓以后开 ...
- NoSQL 数据库管理工具,搭载强大支持:Redis、Memcached、SSDB、LevelDB、RocksDB,为您的数据存储提供无与伦比的灵活性与性能!
NoSQL 数据库管理工具,搭载强大支持:Redis.Memcached.SSDB.LevelDB.RocksDB,为您的数据存储提供无与伦比的灵活性与性能! [官网地址]:http://www.re ...
- GIS中XYZ瓦片的加载流程解析与实现
1. 什么是XYZ瓦片 XYZ瓦片是一种在线地图数据格式,常见的地图底图如Google.OpenStreetMap 等互联网的瓦片地图服务,都是XYZ瓦片,严格来说是ZXY规范的地图瓦片 ZXY规范的 ...
- rbenv 使用指南
https://github.com/rbenv/rbenv https://www.cnblogs.com/yiluhuakai/p/9414730.html https://ruby-china. ...