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 ...
随机推荐
- HarmonyOS创作激励计划启动:助力技术创作突破边界
即日起推出HarmonyOS创作激励计划,成功投稿并入选的文章将在HarmonyOS开发者公众号上线,9大技术社区同步宣发,不仅有丰厚稿酬,还有机会赢取创作奖品! 活动时间 即日起-2024年12 ...
- 4天带你上手HarmonyOS ArkUI开发
本次HarmonyOS ArkUI入门训练营课程--健康生活实战篇,手把手教大家如何制作一个合理膳食的APP前端Demo! 课程实战样例通过ArkUI声明式UI开发框架实现,只需用几行简单直观的声明式 ...
- k8s之helm部署mysql集群
一.简介 Helm Helm 是 Kubernetes 的包管理器. Chart Helm使用的包格式称为 chart.chart存储在Chart Repository. chart就是一个描述Kub ...
- Excel 字符串拆分
用 Excel 处理数据时,有时需要对字符串进行拆分.对于比较简单的拆分,使用 Excel 函数可以顺利完成,但碰到一些特殊需求,或者拆分的规则比较复杂时,则很难用 Excel 实现了.这里列出一些拆 ...
- 实战指南:使用 xUnit 和 ASP.NET Core 进行集成测试【完整教程】
引言 集成测试可在包含应用支持基础结构(如数据库.文件系统和网络)的级别上确保应用组件功能正常. ASP.NET Core 通过将单元测试框架与测试 Web 主机和内存中测试服务器结合使用来支持集成测 ...
- 力扣1620(java&python)-网络信号最好的坐标(中等)
题目: 给你一个数组 towers 和一个整数 radius . 数组 towers 中包含一些网络信号塔,其中 towers[i] = [xi, yi, qi] 表示第 i 个网络信号塔的坐标是 ...
- Beetl 源码解析:GroupTemplate 类
本文首发于公众号:腐烂的橘子 前言 Beetl 是一款 Java 模板引擎,在公司的项目中大量运用,它的作用是写通用代码时,有一些差异化的逻辑需要处理,这时可以把这些差异化的逻辑写在模板里,程序直接调 ...
- Web3开发者技术选型:前端视角(next.js)
引言 在现代Web开发的世界中,Web3技术的兴起为前端开发者开辟了新的可能性.Web3技术主要指的是建立在区块链基础上的分布式网络,使用户能够通过智能合约和去中心化应用(DApps)直接交互,而无需 ...
- 动态尺寸模型优化实践之Shape Constraint IR Part II
简介: 在本系列分享中我们将介绍BladeDISC在动态shape语义下做性能优化的一些实践和思考.本次分享的是我们最近开展的有关shape constraint IR的工作,Part II 中我们将 ...
- Spring Boot 微服务性能下降九成!使用 Arthas 定位根因
简介: 接收到公司业务部门的开发反馈,应用在升级公司内部框架后,UAT(预生产)环境接口性能压测不达标. 背景 接收到公司业务部门的开发反馈,应用在升级公司内部框架后,UAT(预生产)环境接口性能压测 ...