equals && deepEquals

本文分为以下几个部分

equals

deepEquals

总结

equals

首先说明:这里说的 equalsjava.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的更多相关文章

  1. 【Java】Objects 源码学习

    2017-02-10 by 安静的下雪天  http://www.cnblogs.com/quiet-snowy-day/p/6387321.html    本篇概要 Objects 与 Object ...

  2. 【Java】java.util.Objects 源码学习

    2017-02-10 by 安静的下雪天  http://www.cnblogs.com/quiet-snowy-day/p/6387321.html    本篇概要 Objects 与 Object ...

  3. JDK1.8源码(四)——java.util.Arrays类

    一.概述 1.介绍 Arrays 类是 JDK1.2 提供的一个工具类,提供处理数组的各种方法,基本上都是静态方法,能直接通过类名Arrays调用. 二.类源码 1.asList()方法 将一个泛型数 ...

  4. Java中Arrays数组工具类的使用全解

    本文几乎涵盖了所有的Arrays工具类(基于Java 11)的方法以及使用用例,一站式带你了解Arrays类的用法,希望对大家有帮助. 码字不易,三连支持一下吧 Arrays数组工具类 方法一览表 快 ...

  5. 《Java编程思想》学习笔记(详细)

    目录 01 对象导论 02 一切都是对象 03 操作符 04 控制执行流程 05 初始化与清理 06 访问权限控制 07 复用类(继承) 08 多态 09 接口 10 内部类 11 持有对象 12 通 ...

  6. equals变量在前面或者在后面有什么区别吗?这是一个坑点

    我就不废话那么多,直接上代码: package sf.com.mainTest; public class Test { public static void main(String[] args) ...

  7. 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 ...

  8. 【特种兵系列】String中的==和equals()

    1. 小样示例 public static void main(String[] args) { String a = "a" + "b" + 123; Str ...

  9. (转)浅谈Java中的equals和==

    原文地址: http://www.cnblogs.com/dolphin0520/p/3592500.html 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new S ...

  10. 浅谈Java中的equals和==(转)

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...

随机推荐

  1. 《深入理解Java虚拟机》读书笔记:内存分配策略

    Java技术体系中所提倡的自动内存管理最终可以归结为自动化地解决了两个问题:给对象分配内存以及回收分配给对象的内存.关于回收内存这一点,我们已经使用了大量篇幅去介绍虚拟机中的垃圾收集器体系以及运作原理 ...

  2. 【译】Visual Studio 中的 GitHub Copilot:2023年回顾

    在快速发展的软件开发世界中,保持领先是至关重要的.在 Visual Studio 中引入AI,特别是 GitHub Copilot,已经彻底改变了开发人员的编码方式.通过将 Copilot 集成到 V ...

  3. hibernate4升级5带来的一些参数变化

    public String hqlToHibernate5(String hql) { String[] tmp = hql.split(" "); String hqlTmp = ...

  4. The request client is not a secure context and the resource is in more-private address space `privat

    Chrome跨域问题:has been blocked by CORS policy: The request client is not a secure context and the resou ...

  5. Django框架——模版层之标签、自定义过滤器 标签及inclusion_tag(了解)、模版的继承与导入、模型层之前期准备、ORM常用关键字

    模版层之标签 {% if 条件1(可以自己写也可以用传递过来的数据) %} <p>今天又是周三了</p> {% elif 条件2(可以自己写也可以用传递过来的数据) %} &l ...

  6. 力扣461(java)-汉明距离(简单)

    题目: 两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目. 给你两个整数 x 和 y,计算并返回它们之间的汉明距离. 示例 1: 输入:x = 1, y = 4输出:2解释:1 ...

  7. 云原生时代如何用 Prometheus 实现性能压测可观测-Metrics 篇

    ​简介:可观测性包括 Metrics.Traces.Logs3 个维度.可观测能力帮助我们在复杂的分布式系统中快速排查.定位问题,是分布式系统中必不可少的运维工具. 作者:拂衣 什么是性能压测可观测 ...

  8. 技术解读:英特尔 x86 平台上,AI 能力是如何进行演进的?(附PPT)

    ​简介:AI 生态系统是怎样的?其中又有哪些关键技术? AI 计算力的指数增长意味着,为了解决越来越复杂的用例,即使是 1000 倍的计算性能增长也很容易被消耗.因此,需要通过软件生态系统的助力,才能 ...

  9. 百信银行基于 Apache Hudi 实时数据湖演进方案

    简介: 本文介绍了百信银行实时计算平台的建设情况,实时数据湖构建在 Hudi 上的方案和实践方法,以及实时计算平台集成 Hudi 和使用 Hudi 的方式. 本文介绍了百信银行实时计算平台的建设情况, ...

  10. 链路分析 K.O “五大经典问题”

    ​简介:链路分析是基于已存储的全量链路明细数据,自由组合筛选条件与聚合维度进行实时分析,可以满足不同场景的自定义诊断需求. 作者:涯海 链路追踪的 "第三种玩法" 提起链路追踪,大 ...