Guava ImmutableCollection簡介

ImmutableCollection代碼定義

@GwtCompatible(emulated=true)
public abstract class ImmutableCollection<E> extends AbstractCollection<E> 
        implements Serializable

ImmutableCollection表示內容不可更改的集合,並提供以下額外特性的擔保。

注意:應當避免直接使用ImmutableCollection作爲一個類型,就如同避免直接使用Collection本身一樣。最好使用其子類(例如ImmutableSet或ImmutableList),因爲子類擁有更好的Object.equals(java.lang.Object) 語義,可以從源頭避免常見的bug和錯誤。

以下文檔適用於com.google.common.collect包中所有公開的不可變類型,不論是否是ImmutableCollection的子類。

保證特性

  • 淺不可變

淺不可變是指值是不可寫的,但是如果是對象的引用的值是可被改變的。不能對不可變集合的元素進行增加、移除或者替換。這是比Collections.unmodifiableCollection 更嚴格的保證,因爲這個集合的內容會隨其包裝集合的改變而改變。

  • 不可爲Null

本集合不能包含null元素。

  • 確定性的迭代

元素迭代順序是被定義的,取決於集合的創建(細節可以參考對應的工廠方法)。除非另外註明,集合視圖(例如ImmutableMultiset.elementSet())的迭代順序與父集合一樣。

  • 線程安全

多線程併發訪問集合是安全的。

  • 完整性

本類型不能在除com.google.common.collect包以外被繼承。(因爲這有可能違反以上擔保特性。)

接口而非實現

每一個公開的類(例如ImmutableSet)都是一個提供具體功能行爲保證的類型,而不僅僅是在某種特定的實現(例如ArrayList)。對類型名稱的含義都應當理解爲是接口而非實現。

屬性類型和方法返回類型通常都應當使用不可變類型(例如ImmutableList)而不是一般的集合接口(例如List)。這樣便於告知調用者以上對於類型的保證特性,這是非常有用的信息。

另一方面,直接將ImmutableList作爲參數類型並不令人滿意。解決方案是接受Iterable類型參數,通過方法或構造器將它傳遞給相應的copyOf方法。

創建

除了邏輯層面的抽象類(例如ImmutableCollection),每個不可變類型都提供了或者此類型實例的靜態方法。最常用的有:
1、靜態方法of,接受一個顯示的元素或條目列表。
2、靜態方法copyOf(或者copyOfSorted),接受一個內容可被複制的已存在的集合。
3、嵌套的靜態類Builder,它可以用來填充一個新的不可變實例。

警告

如任何集合一樣,改變集合中的元素(這種改變影響了Object.equals(java.lang.Object)的行爲)是一種錯誤的做法。他會引起未定義的行爲和bug。通常最佳實踐是完全避免使用可變對象作爲集合元素,雖然許多用戶認爲不可變對象是深不可變的(deeply immutable)。

性能說明

1、集合的實現通常優先考慮內存效率,然後是訪問速度,最後是創建速度。
2、copyOf方法有時會認爲沒有必要進行實際複製操作:例如,copyOf(copyOf(anArrayList))只會複製一次。這減少了在API邊界習慣性地創建防禦副本的代價。但是,跳過拷貝操作的精確情況是未定義的。
3、警告:視圖集合(例如ImmutableMap.keySet或ImmutableList.subList(int,int))會保留對整個數據集合的引用,以防止其被垃圾收集。如果其中一些數據通過其他方式不再可用,這可能會產生內存泄漏。可通過傳遞視圖集合給適當的copyOf方法以獲得正確大小的拷貝。
4、與創建可變集合並拷貝相比,使用相應關聯的Builder類並不會降低性能,有可能會更好。
5、通常實現不會緩存hash code。如果元素或鍵類型的hashCode實現較慢,它應當自己實現緩存。

使用示例


   class Foo {
     private static final ImmutableSet<String> RESERVED_CODES =
         ImmutableSet.of("AZ", "CQ", "ZX");

     private final ImmutableSet<String> codes;

     public Foo(Iterable<String> codes) {
       this.codes = ImmutableSet.copyOf(codes);
       checkArgument(Collections.disjoint(this.codes, RESERVED_CODES));
     }
   }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章