guava 集合上 三 原

 

Immutable Collections

不可變對象有很多優點

   1.對於不信任的庫使用安全

   2.對於多線程不會出現多個線程競態的情況

   3.不需要支持變化,使得在空間和時間上都能夠固定下來,不可變的對象在內存方面更加高效

    4.可以作爲常量使用

      對於對象的不可變拷貝是編程的一種防禦式方法,guava提供了對於collection中每個類型簡單,方便的不可變拷貝,包含guava的集合變量不可變拷貝。

 

比較jdk和guava中的不可變集合

jdk中提供了collections.unmodifiablexxx 方式,但是看來,有以下缺點

  • 不夠廣泛而冗長,不能在想要做拷貝的任何地方使用
  • 不安全:如果沒有持有原有對象的引用,返回的集合不可變
  • 不夠高效:上面還有可變集合的數據結構的方面,有修改的併發檢查,使用到hash 表中額外的空間。
  • 當你不期望修改一個集合,或者一個集合作爲常量使用,一個好的方法就是將它拷貝成不可變的另一個集合

創建不可變對象

  • 使用copyof方式,ImmutableSet.copyOf(set)
  • 使用of的方式,ImmutableSet.of("a","b","c") ImmutableMap.of("a",1,"b",2)
  • 使用構造器模式Builder 

eg

build方法

public static final ImmutableSet<Color> GOOGLE_COLORS = ImmutableSet.<Color>builder()

.add(new Color(0, 191, 255))

.build();

期望排過序的集合,構造集合的時候,順序已經保存了下來

ImmutableSet.of("a","b","c","d");

 

copyOf方法

ImmutableSet<String> foobar = ImmutableSet.of("foo", "bar", "baz");

public ImmutableList doCopy(Collection<String> collection) {

return ImmutableList.copyOf(collection);

}

 

@Test

public void testImmutableList(){

doCopy(foobar);

}

上面的代碼中,ImmutableList.copyOf(foobar) 足夠智能的返回了foobar.asList(),在ImmutableSet看來是常數時間類型

通常的啓發式當中,ImmutableXXX.copyOf(ImmutableCollection)試着避免線性時間拷貝

1.可以在常數時間內使用已定義的數據結構,如ImmutableSet.copyOf(ImmutableList) 不能夠在線性時間內完成

2.不會引起內存泄漏,例如,如果有一個大的不可變列表,使用了ImmutableLIst.copyOf(hugeList.subLIst(0,10)),一個明確的拷貝被執行,避免突然持有對整個hugeList的引用;

3.不會改變語義,ImmutableSet.copyOf(myImmutableSortedSet)執行精確的拷貝,因爲ImmutableSet使用的hashCode和equals與ImmutableSortedSet在基於比較方面有不同的語義含義。

 

這些減少了防禦性編程style性能方面消耗

asList

所有不變的集合通過asList()提供了不變的列表,例如,有保存在ImmutableSortedSet中的數據,可以使用sortedSet.asLIst().get(k)獲取第k小的元素

ImmutableList是頻繁的,不經常的,通常看作一個常量,而不是一個精確的複製,它比普通的list更高效,例如,可以使用返回數據集合中更高效的contains方法。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章