日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

float foo=42e1为什么错_为什么重写了equals()也要重写hashCode()

發布時間:2023/12/9 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 float foo=42e1为什么错_为什么重写了equals()也要重写hashCode() 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

小Hub領讀:

雖然是很基礎的一篇文章,但是對于equals、hashcode兩個方法,相信很多人都與其中的規則不熟悉,來跟著小Hub花個8分鐘回顧一下!


作者:不學無數的程序員

https://my.oschina.net/u/4030990/blog/3134199

在?EffectiveJava中第九條規定在覆蓋?equals()方法時總要覆蓋?hashCode()方法。這是為什么呢?接下來我們就介紹一下這兩個方法。

Java中的?equals()方法和?hashCode()方法都是在?Object類中的方法,而在Java中所有的類都是?Obejct類的子類,所以Java中所有的方法都會有這兩個方法的默認實現。

equals方法

Object類中的?equals()方法定義如下

public boolean equals(Object obj) {

return (this == obj);

}

我們發現在?equals()方法中就關鍵的?==,那么?==在Java中有什么含義呢,我們都知道在Java中分為基本數據類型和引用數據類型。那么?==在這兩個類型中作用是不一樣的。

  • 基本數據類型:比較的是?==兩邊值是否相等

  • 引用數據類型:比較的是?==兩邊內存地址是否相等

基本數據類型包括:?byte,?short,?char,?int,?long,?float,?double,?boolean

而通過Java文檔中的?equals()方法描述,所有要實現自己的?equals()方法都要遵守下面幾個規則

  • 自反性:對于任何對象x,?x.equals(x)應該返回?true

  • 對稱性:對于任何兩個對象x和y,如果?x.equals(y)返回?true,那么?y.equals(x)也應該返回?true

  • 傳遞性:對于多個對象x,y,z,如果?x.equals(y)返回?true,?y.equals(z)返回?true,那么?y.equals(z)也應該返回?true

  • 一致性:對于兩個非空對象x,y,在沒有修改此對象的前提下,多次調用返回的結果應該相同

  • 對于任何非空的對象x,?x.equals(null)都應該返回?false

hashCode方法

Object中的?hashCode()方法是一個本地方法,返回一個?int類型的哈希值。

public native int hashCode();

在?hashCode()方法中也有一些規約

  • 如果對象在使用?equals方法中進行比較的參數沒有修改,那么多次調用一個對象的?hashCode()方法返回的哈希值應該是相同的。

  • 如果兩個對象通過?equals方法比較是相等的,那么要求這兩個對象的?hashCode方法返回的值也應該是相等的。

  • 如果兩個對象通過?equals方法比較是不同的,那么也不要求這兩個對象的?hashCode方法返回的值是相同的。但是我們應該知道對于不同對象產生不同的哈希值對于哈希表(HashMap等等)能夠提高性能。

equals方法和hashCode方法會在哪用到

這兩個方法經常出現在Java中的哪個類里面呢?如果看過?HashMap源碼的應該了解這兩個方法經常出現在?HashMap中。網上介紹?HashMap類的文章有很多了,這里就簡單介紹一下?HashMap。

當一個節點中的鏈表超過了8的時候就會變為紅黑樹,以解決鏈表長度過長以后查詢速度慢的缺點。

HashMap是由數組和鏈表組成的高效存儲數據的結構。那么是如何確定一個數據存儲在數組中的哪個位置呢?就是通過?hashCode方法進行計算出存儲在哪個位置,還記得我們上面講?hashCode方法說了有可能兩個不同對象的?hashCode方法返回的值相同,那么此時就會產生沖突,產生沖突的話就會調用?equals方法進行比對,如果不同,那么就將其加入鏈表尾部,如果相同就替換原數據。

計算位置當然不是上面簡單的一個?hashCode方法就計算出來,中間還有一些其他的步驟,這里可以簡單的認為是?hashCode確定了位置。

什么時候去覆蓋這兩個方法呢?

如果你不將自定義的類定義為?HashMap的key值的話,那么我們重寫了?equals方法而沒有重寫?hashCode方法,編譯器不會報任何錯,在運行時也不會拋任何異常。

如果你想將自定義的類定義為?HashMap的key值得話,那么如果重寫了?equals?方法那么就必須也重寫?hashCode方法。

接下來我們可以看一下我們使用自定義的類作為?HashMap的key,并且自定義的類不重寫?equals和?hashCode方法會發生什么。

自定義的類

@Builder

@NoArgsConstructor

@AllArgsConstructor

class CustomizedKey{

private Integer id;

private String name;

}

接下來我們看使用自定義的類作為key

public static void main(String[] args) {

Map<CustomizedKey, Integer> data = getData();

CustomizedKey key = CustomizedKey.builder().id(1).name("key").build();

Integer integer = data.get(key);

System.out.printf(String.valueOf(integer));

}

private static Map<CustomizedKey,Integer> getData(){

Map<CustomizedKey,Integer> customizedKeyIntegerMap = new HashMap<>();

CustomizedKey key = CustomizedKey.builder().id(1).name("key").build();

customizedKeyIntegerMap.put(key,10);

return customizedKeyIntegerMap;

}

我們可以看到程序最后打印的是一個?null值。原因正如上面我們說的一樣。

  • hashCode:用來計算該對象放入數組中的哪個位置,因為是兩個都是new的對象,所以即使里面的值一樣,但是對象所處的地址卻不同,所以使用默認的?hashCode也就不同,當然在?hashMap中就不會認為兩個是一個對象。

接下來我們就重寫一下這兩個方法。如果我們使用?IDEA的話,那么直接使用快捷鍵即可。

接下來我們看我們實現的兩個方法

@Builder

@NoArgsConstructor

@AllArgsConstructor

class CustomizedKey{

private Integer id;

private String name;

@Override

public boolean equals(Object o) {

if (this == o) return true;

if (o == null || getClass() != o.getClass()) return false;

CustomizedKey that = (CustomizedKey) o;

return Objects.equals(id, that.id) &&

Objects.equals(name, that.name);

}

@Override

public int hashCode() {

return Objects.hash(id, name);

}

}

然后我們再次運行上面的程序發現輸出打印已經變成了?10。

我們也能夠使用?Lombock提供的?@EqualsAndHashCode注解簡化代碼

代碼地址:https://github.com/modouxiansheng/Doraemon


(完)

MarkerHub文章索引:

https://github.com/MarkerHub/JavaIndex

【推薦閱讀】

知乎問答:搞開發就怕加班還學不到東西?

很全很牛逼,看完這篇Elasticsearch實戰,我覺得我可以寫個百度~

基于Jwt資源無狀態認證權限管理系統bootshiro

別用Date了,Java8新特性之日期處理,現在學會也不遲!

eblog項目講解視頻上線啦,長達17個小時!!

好文章!點個在看!

總結

以上是生活随笔為你收集整理的float foo=42e1为什么错_为什么重写了equals()也要重写hashCode()的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。