2013-04-24 64 views
1

思考說:這是一種在Java中創建只讀列表的方法嗎?在Java中

要創建AbstractList的只讀列表中,您必須農具get()和大小()。

它搞糊塗了,代碼如下:

public class CountingIntegerList 
extends AbstractList<Integer> { 
    private int size; 
    public CountingIntegerList(int size) { 
    this.size = size < 0 ? 0 : size; 
    } 
    public Integer get(int index) { 
    return Integer.valueOf(index); 
    } 
    public int size() { return size; } 
    public static void main(String[] args) { 
    List list = new CountingIntegerList(30); 
    } 
} 

是列出一個只讀的目錄?爲什麼?

好吧,答案是肯定的,因爲我擴展了AbstractList,如果setand被調用,它會丟失UnsupportedOperationException。如果我想得到一個不可修改的列表,Collections.unmodifiableList()是一個不錯的選擇。但要記住,他們兩人都沒有深入一成不變:

 List<StringBuilder> list = new ArrayList<StringBuilder>(); 
     StringBuilder sb = new StringBuilder(); 
     sb.append("hello"); 
     list.add(sb); 
     System.out.println(list); 
     list = Collections.unmodifiableList(list); 
     sb.append("world"); 
     System.out.println(list); 

有在CountingIntegerList一個flyweight pattern。因爲每次get()被調用,它從整型的valueOf()源代碼獲得緩存:

public static Integer valueOf(int i) { 
    final int offset = 128; 
    if (i >= -128 && i <= 127) { // must cache 
     return IntegerCache.cache[i + offset]; 
    } 
     return new Integer(i); 
    } 

是否是正確的?

+0

這是可能的方法之一。 爲什麼?正如你所看到的,你不能添加任何元素到這個List ..(不是通過add方法。)我會建議有parameterised構造函數來接受初始List。否則你的不可修改列表將永遠不會有任何數據 – 2013-04-24 13:33:47

+0

哪一部分讓你感到困惑? – mikej 2013-04-24 13:34:30

+0

'你的不可修改列表將永遠不會有任何數據'? – znlyj 2013-04-24 13:39:50

回答

4

因爲set拋出一個UnsupportedOperationException,如果沒有實現。見Api

+0

啊哈,也許我應該先熟悉api,謝謝! – znlyj 2013-04-24 13:34:50

1

傳遞的ArrayList到Collections.unmodifiableList()

返回指定列表的不可修改視圖。該方法允許 模塊爲用戶提供對內部列表的「只讀」訪問權限。 在返回列表「通過讀取」到指定的 列表上查詢操作,並試圖修改返回的列表,無論是直接還是通過 其迭代器,都會導致UnsupportedOperationException異常。如果指定的列表是可序列化的,則返回的 列表將是可序列化的。 同樣,如果指定列表中有 ,返回的列表將執行RandomAccess。

4

你可以包裝在UnmodifiableList

List readOnlyList = Collections.unmodifiableList(yourList) 
5

您的列表它的只讀(甚至是不可變的),因爲add將拋出UnsupportedOperationException如將remove

AbstractList處理所有創建迭代器的工作, 爲您計算哈希碼和平等。這非常有幫助。 完全沒有必要包裝在unmodifiableList中。

後來你問是否AbstractList主要用於創建不可修改的列表。實際上它被用來創建任何類型的隨機訪問列表。在我的數據結構課程中,我們使用這樣的抽象類來保存大部分實現列表類的工作。即使是Collection接口也有13種方法,除AbstractCollection之外,其餘兩種都是實現的。

有相關的類AbstractSequentialList可幫助創建非隨機訪問列表(如鏈接列表)。

+0

對不起,但我不清楚「完全不需要包裝在不可修改的列表中」。你能解釋我嗎? – znlyj 2013-04-24 13:36:51

+0

您創建的列表沒有任何方式可能發生變化。 unmodifiableList包裝將確保addremove將引發異常,但由於它們無論如何,包裝只是浪費空間和時間。 – 2013-04-24 13:39:02

+0

如果你擴展AbstractList,那麼你不需要用'unmodifiableList'來包裝它。 如果你想使用你現有的Collection類,比如ArrayList,那麼你可以通過用'unmodifiableList'包裝它來使其不可修改。 – 2013-04-24 13:40:14

0

這有點棘手。該列表不能改變和/或元素? ;)

StringBuilder builder = new StringBuilder(); 
    builder.append("Hello"); 
    List<StringBuilder> list = new ArrayList<StringBuilder>(); 
    list.add(builder); 

    Collection<StringBuilder> canNotChange = Collections.unmodifiableCollection(list); 
    builder.append(" World"); 
    System.out.println(canNotChange.iterator().next()); 
+0

但是你沒有改變名單,不是嗎?該清單像以前一樣保存參考元素。 – znlyj 2013-04-24 14:01:32

+0

@znlyj yup。這是不可變的和深不可變的區別。這取決於你的需求。 – Eugene 2013-04-24 14:02:16

+0

所以我的'CountingIntegerList'不是非常不可變的。 'Collections.unmodifiableList'不能創建一個非常不可變的列表。 – znlyj 2013-04-24 14:14:50

相關問題