簡體   English   中英

如何確定我的班級是一成不變的

[英]How can I be sure that my class is immutable

我需要創建一個非常類似於String的類,但是該對象必須存儲一個字節數組,而不是存儲字符數組,因為我將處理二進制數據,而不是字符串。

我在應用程序中使用HashMaps。 因此,我很想使我的自定義byteArray類不可變,因為不可變對象在哈希圖中執行更快的搜索。 (我想要這個事實的消息來源)

我很確定我的課程是不可變的,但是在哈希映射搜索中,它與字符串相比仍然表現不佳。 如何確定它是不可變的?

最重要的是將字節復制到數組中。 如果你有

this.bytes = passedInArray;

調用方可以修改passedInArray,從而修改this.bytes。 必須

this.bytes = Arrays.copyOf(passedInArray, passedInArray.length);

(或者類似,克隆也可以)。 如果此類將主要用作Maps中的鍵,那么我會立即(在構造函數中)計算哈希碼,這比懶惰地簡單。

實現明顯的equals() ,我認為您已經完成了。

您的問題是“我如何確定我的課堂是不變的?” 我不確定您要問的是什么意思,但是Josh Bloch在《 有效Java》第二版中列出了使類不可變的方法 這里的項目15中,我將在此答案中進行總結:

  1. 不要提供任何mutator方法(改變對象狀態的方法,通常稱為“ setters”)。
  2. 確保該類不能擴展。 通常,將課程定為最終課程。 這使其他人無法對其進行子類化和修改受保護的字段。
  3. 將所有字段定為最終字段,這樣就無法更改它們。
  4. 將所有字段設為私有,以便其他人不能更改它們。
  5. “確保對可變組件的專有訪問。” 也就是說,如果其他內容指向該數據並因此可以更改它,則進行防御性復制(如@ user949300所指出)。

請注意,不可變的對象不會自動產生很大的性能提升。 不可變對象的好處在於不必鎖定或復制該對象,以及重新使用它而不是創建一個新對象。 我相信HashMap中的搜索使用該類的hashCode()方法,並且查找應為O(c)或恆定時間和快速速度。 如果您遇到性能問題,則可能需要查看hashCode()方法是否緩慢(不太可能)或其他地方是否存在問題。

一種可能性是,如果您實現的hashCode()很差(或根本沒有實現),並且在HashMap引起大量沖突-也就是說,使用類的不同實例調用該方法將返回相似或相同的值- -然后,實例將存儲在hashCode()指定的位置的鏈表中。 遍歷此列表會將您的效率從恆定時間轉換為線性時間,從而使性能變得更差。

因為不可變對象在哈希圖中執行更快的搜索。 (我想要這個事實的消息來源)

不,這不是真的。 作為哈希映射鍵的性能將由hashCode的運行時以及避免沖突來確定。

我很確定我的課程是不可變的,但是在哈希映射搜索中,它與字符串相比仍然表現不佳。 如何確定它是不可變的?

您的問題很可能是對hashCode實現的錯誤選擇。 考慮基於Arrays.hashCode實現您的實現。

(您的問題ArrayList <Byte> vs Java在Java中建議您嘗試調整特定的實現;使用byte[]的建議很好。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM