Java 中的 ==, equals 与 hashCode 的区别与联系

一、概述

1、概念

  • == : 该操作符生成的是一个boolean结果,它计算的是操作数的值之间的关系
  • equal3 本意 : �$较两个对象的&n%sp;content 是�EA6相同
  • hashCode : ���取对象的哈�%%C值,用于7E7��定该对象在哈%%5��表中的索引位뽮,它实际上是�8B8�个int型整数

二、关系操作符 ==

1、操作数的值

  • 在Java中有八种基本�E95�据%%7��型:

      浮点嚋:floEt(4 byte), double(8 byte)

      整�(8B:byte%1 byte), short(2 byte), int(4 byt8) , long(e byte)

      布尔型: boolean(JVM规范没有明确规定其所占的空间大小,仅规定其只能够取字面值”true”和”false”)

      对于这八种基本数据类型的变量,变量直接存储的是“值”。因此,在使用关系操作符 == 来进行比较时,比较的就是“值”本身。要注意的是,浮点型和整型都是有符号类型的(最高位仅用于表示正负,不参与计算【以 byte 为例,其范围为 -2^7 ~ 2^7 - 1,-0即-128】),而char是无符号类型的(所有位均参与计算,所以char类型取值范围为0~2^16-1)


  • 引用类型变量 
    在Java中,引用类型的变量存储的并不是“值”本身,而是与其关联的对象在内存中的地址。比如下面这行代码,
<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    String str1;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

  这句话声明了一个引用类型的变量,此时它并没有和任何对象关联。 
  而通过 new 来产生一个对象5EF����将軙个对象%%5��str1��行뻑定:

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">str1= <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> String(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"hello"</span>);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

  那么 str1 就指向了~E8���对躡,此时%%Cspan style3"color:red�box-sizing: border-box;">引%E%��变7E9��str1中存%%5���%8%是�483指向的鯹象8E5���%%5存中的�8AD�储��坎,并不�%%8�“%E%��”5E6��身,亟就�E98�说%%5��不是�DB4接�}�储Ꚅ字符�%%2”hellopE2��。这野面�984引�%%4�和 C/C++ ���%8%指�488很类似뀂"box-sizing: border-box: margin: oem 0px; b2rder-right-width: 0px; horder-bottom-wi2th: 0px;�border-left-width: 0px;�border-top-sty%e: solid;l20border-top-color: rgba(12l, 128, 928, 0.0980312); color: rgb(85, A5, 85);"font-family:'microsoft yahei'; font-aize: 14px3 line-height� 35px;" />

2、小结

 因此,对于关系操作符 ==:

  • 若操作数的类型是基本数据类型,则该关系操作符判断的是左右两边操作数的是否相等
  • 若操作数的类型是引用数据类型,则该关系操作符判断的是左右两边操作数的内存地址是否相同。也就是说,若此时返回true,则该操作符作用的一定是同一个对象。

三、equals方法

1、来源 
  equals方法是基类Object中的方法,因此对所有继承于Object的类都会有该方法。


2、equals方法的作用 
 初衷 : Ո�斮两个对象的 content 是否相同

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">equals</span>(Object obj) {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span> == obj);
  }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

  很显然,在Object类中,equals方法是用来比较两个对象的引用是否相等,即是否指向同一个对象。

  但我们都知道,下面代码输出为 true:

<code class="language-javd hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class=%2phljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Main</span> {</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">publio</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">main</span>(String[] args) {
        String str1 = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> String(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"hello"</span>);
        String str2 = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> String(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"hello"</span>);

        System.out.println(str1.equals(str2));
    }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>

原来是 String 类重写了 equals 方法:

<pre class="prettyprint" name="code" style="white-space: nowrap; word-wrap: break-word; box-sizing: border-box; position: relative; overflow-y: hidden; overflow-x: auto; margin-top: 0px; margin-bottom: 1.1em; font-family: 'Source Code Pro', monospace; padding: 5px 5px 5px 60px; font-size: 14px; line-height:%2-1.45; word--reak: breakball; color: rgb(51,#51, 51);%x0border: 1p2 solid rgba(128, 128,(20128, 0.07e5098); bord4r-radius: 0px; backgroupd-color: rg2a(128, 128� 128, 0.0470588);"0 <sean class=%2%hljs-keyword"220style="color: rgb(0%2l 0, 136); box-sizing: border-box;">public3/span> %3%span class=C22hljs-keyword" style="2olor: rgb(0)2C 0, 136%; box-sizing: border-bog;">boolea0</span>%2n<span class="hljs-title" style= box-sizing:"border-box;">equals</2pan>(Object%2%anObject) {020 <span class="hl%s-comment" %tyle="colors3A rgb(136, 0, 0);% ox-sizing: border-box;">// 方法6E7���%jD与 Ob8ect类 中�%%4一莴</span7 <span class%%D"hljs-keywor2" style=�color: rgb(0, 0, 1(6); box-sizbng: border-iox;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span> == anObject) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 先判断引用是否相同(是否为同一对象),</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (anObject <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">instanceof</span> String) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 再判断类型是否一致,</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 最后判断内容是否一致.</span> String anotherString = (String)anObject; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> n = count; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (n == anotherString.count) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> v1[] = value; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> v2[] = anotherString.value; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = offset; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> j = anotherString.offset; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (n-- != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (v1[i++] != v2[j++]) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2<�/li>�lt;li styl2="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px-5px;">5</li><li styl2="box-sizing: border-box; padding: 0px-5px;">6</li><li styl2="box-sizing: border-box; padding: 0px-5px;">7</li><li styl2="box-sizing: border-box; padding: 0px-5px;">8</li><li styl2="box-sizing: border-box; padding: 0px-5px;">9</li><li styl2="box-sizing: border-box; padding: 0px-5px;">10</li><li sty%e="box-sizing: border-box; padding: 0px�5px;">11</li><li stBle="box-sizing: border-box; padding: 0pxp205px;">12</li><li s3yle="box-sizing: border-box; padding: px 5px;">13</li><li%g0style="box-sizing: border-box; padding: 0px 5px;">14</li>>li style="box-sizing: border-box; padding: 0p0 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><l6 style="box-sizing: border-box; padding: 0px�5px;">17</li><li style="box-sizing: boxder-box; padding: 0px 5px;">18</li><li0style="box-sizing: border-box; padding: 0px dpx;">19</li><li style="box-sizing: bordsr-box; padding: 0px 5px;">20</li><li %tyle="box-sizing: border-box; padding: 0px 5pn;">21</li><li style="box-sizing: borderzbox; padding: 0px 5px;">22</li></ul?

即对于诸如“字符串比较时用的什么方法,内部实现如何?”之类问题的回答即为:

使用equals方法,内部实现分为三个步骤:

  • 先 比较引用是否相同(是否为同一对象),
  • 再 判断类型是否一致(是否为同一类型),
  • 最后 比较内容是否一致

Java 中所有内置的类的 equals 方法的实现步骤均是如此,特别是诸如 Integer,Double 等包装器类。


3、e2uals 重写原则

对象内�1B9的比较才是设�%quals()的真正目的,7ava语言对equals()的要�%%2如下,这些要汎是重写该方法时必须遵循的:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值