2011-03-05 105 views
32

是否可以定義一個固定大小爲100的列表?如果不是,爲什麼不在Java中可用?在Java中定義一個固定大小的列表

+1

您可以設置ArrayList的起始大小,但是如果添加更多元素,它會自行擴展 – 2011-03-05 22:22:38

+5

固定或最大?你想要列表不能超過100個項目?如果嘗試add(),會發生什麼?例外,沒有,或者丟棄一個現有的元素來支持新的元素。 – Bozho 2011-03-05 22:24:07

+7

這些野獸是不是叫做「數組」? – 2011-03-05 22:33:54

回答

14

Commons library提供了一個內置的FixedSizeList不支持addremoveclear方法(但該set方法允許的,因爲它不修改List的大小)。換句話說,如果你嘗試調用這些方法之一,你的列表仍然保持相同的大小。

要創建固定大小的列表,只需撥打

List<YourType> fixed = FixedSizeList.decorate(Arrays.asList(new YourType[100])); 
+9

如果已經是固定大小的列表,爲什麼要裝飾Arrays.asList結果? – PhoneixS 2013-01-16 16:54:15

+3

是的......'FixedSizeList.decorate(...)'用於包裝尚未固定大小的列表。在這裏使用它是多餘的。 – 2013-01-17 00:52:17

27

如果沒有記錯這應該這樣做:

List<MyType> fixed = Arrays.asList(new MyType[100]); 
+0

可能會重複,如果您不斷添加它,它會將大小保持爲100嗎? – fastcodejava 2011-03-05 22:22:00

+3

它會拋出一個異常 – Bozho 2011-03-05 22:22:34

+7

@fastcodejava - 你不能使用具有固定長度列表的'add'方法 - 它已經有100個空條目。使用'set'來設置值。 – McDowell 2011-03-05 22:27:07

3

創建大小爲100的數組如果你需要的資源列表界面中,然後調用它Arrays.asList。它將返回一個由數組支持的固定大小的列表。

+0

Upvoted無法解釋的downvote。答案是正確的。 @Downvoter請解釋一下,否則沒人知道什麼,除非在這種情況下你錯了。 – EJP 2012-03-26 22:55:22

11

是的。您可以將一個java數組傳遞給Arrays.asList(Object[])

List<String> fixedSizeList = Arrays.asList(new String[100]); 

您不能將新的字符串插入到fixedSizeList(它已經有100個元素)。您只可以設置它的值是這樣的:

fixedSizeList.set(7, "new value"); 

你有一個固定大小的列表方式。這個東西像一個數組一樣工作,我想不出有什麼好的理由來使用它。我很想聽聽你爲什麼希望你的固定大小的集合成爲一個列表,而不是僅僅使用一個數組。

+0

數組不能被生成。 – 2012-03-30 01:23:36

+0

我的理由和Jeffrey's一樣。震驚得知你不能擁有該行: T [] myGenericArray = new T [5]; – Swiftslide 2012-10-24 01:41:11

+1

這是完美的。而不是「字符串」,我們必須按照要求放置對象類。 – Debarati 2013-09-24 09:26:01

2

如果您想要一些靈活性,請創建一個觀察列表大小的類。

下面是一個簡單的例子。您需要重寫所有更改列表狀態的方法。

public class LimitedArrayList<T> extends ArrayList<T>{ 
    private int limit; 

    public LimitedArrayList(int limit){ 
     this.limit = limit; 
    } 

    @Override 
    public void add(T item){ 
     if (this.size() > limit) 
      throw new ListTooLargeException(); 
     super.add(item); 
    } 

    // ... similarly for other methods that may add new elements ... 
+1

add(int index,T element)方法也需要被覆蓋。 – shams 2011-03-06 15:01:40

+0

@shams:這就是爲什麼我說「你將需要重寫所有的方法來改變列表的狀態」...... – Jeremy 2011-03-06 22:27:13

+0

是的,我認爲處理這兩個就足夠了。 add *是標準接口中唯一可以增加List大小的方法。我認爲其中有四個,但其他兩個(addAll *)依次調用add *方法。 – shams 2011-03-07 03:20:31

25

無論您的問題是誤報,或者你有一個什麼樣的Java的List是不正確的心智模型。


Java列表是一個對象的集合...列表的元素。列表的大小是該列表中元素的數量。如果你想要這個大小是固定的,這意味着你不能添加或刪除元素,因爲添加或刪除元素會違反你的「固定大小」約束。

實現「固定大小」列表(如果這真的是你想要的)最簡單的方法是將元素放入數組,然後Arrays.asList(array)來創建列表包裝。該包裝將允許您執行類似getset的操作,但addremove操作將引發異常。

如果您想爲現有列表創建一個固定大小的包裝,那麼您可以使用Apache公共類FixedSizeList類。但是請注意,這個包裝器不能阻止其他東西改變原始列表的大小,如果發生這種情況,包裝列表可能會反映出這些變化。 (國際海事組織,FixedSizeList的javadoc是可悲的,它不會嘗試記錄當包裹列表發生變化時類的行爲,你需要閱讀源代碼......並希望它們不會改變你的行爲有沒有注意。)


在另一方面,如果你真的想用它的大小固定的限制(或限制)的列表類型,那麼你需要創建自己的列表類來實現這個。例如,您可以創建一個包裝類,在各種add/addAllremove/removeAll/操作中執行相關檢查。 (如果支持,則在迭代器remove方法中。)

那麼爲什麼Java Collections框架沒有實現這些?這就是爲什麼我這麼認爲:

  1. 需要這種情況的用例很少見。
  2. 在需要這種用例的情況下,當操作嘗試突破極限時對於該做什麼有不同的要求;例如拋出異常,忽略操作,丟棄一些其他元素來騰出空間。
  3. 有限制的列表實現可能對輔助方法有問題;例如Collections.sort
+0

好評,但官方java建議現在儘可能使用arraylist而不是array,所以我們將會有很多程序員在將來問這個問題。我正在談論關於java se程序員7的官方書籍。 – arisalexis 2014-11-26 13:55:38

+0

@arisalexis - 1)你在談論哪本書?提供精確的標題/作者...或URL。 2)這本書*是否與我所說的矛盾?或者你只是添加一個(IMO:基本上不相關的)事實? – 2014-11-26 22:40:47

+0

我並不矛盾你的帖子,我只是指出了一些與我無關的東西。在參加OCA java 7考試並閱讀由edward finegan和robert liguori編寫的Oracle書時,它表示「在大多數情況下將數據存儲在數組中的首選方法是使用「列表」。我只是說有時候人們會學習使用數組列表來處理所有事情,然後提出這些問題。 – arisalexis 2014-11-27 09:33:21

8

通常,固定大小的列表是Java數組。默認列表允許在Java中增長/縮小。但是,這並不意味着您不能擁有固定大小的列表。你需要做一些工作並創建一個自定義實現。

您可以使用自定義實現的clear,add和remove方法擴展ArrayList

例如

import java.util.ArrayList; 

public class FixedSizeList<T> extends ArrayList<T> { 

    public FixedSizeList(int capacity) { 
     super(capacity); 
     for (int i = 0; i < capacity; i++) { 
      super.add(null); 
     } 
    } 

    public FixedSizeList(T[] initialElements) { 
     super(initialElements.length); 
     for (T loopElement : initialElements) { 
      super.add(loopElement); 
     } 
    } 

    @Override 
    public void clear() { 
     throw new UnsupportedOperationException("Elements may not be cleared from a fixed size List."); 
    } 

    @Override 
    public boolean add(T o) { 
     throw new UnsupportedOperationException("Elements may not be added to a fixed size List, use set() instead."); 
    } 

    @Override 
    public void add(int index, T element) { 
     throw new UnsupportedOperationException("Elements may not be added to a fixed size List, use set() instead."); 
    } 

    @Override 
    public T remove(int index) { 
     throw new UnsupportedOperationException("Elements may not be removed from a fixed size List."); 
    } 

    @Override 
    public boolean remove(Object o) { 
     throw new UnsupportedOperationException("Elements may not be removed from a fixed size List."); 
    } 

    @Override 
    protected void removeRange(int fromIndex, int toIndex) { 
     throw new UnsupportedOperationException("Elements may not be removed from a fixed size List."); 
    } 
} 
0

如果你想使用ArrayListLinkedList,看來答案是否定的。儘管java中有一些類可以將它們設置爲固定大小,如PriorityQueue,但ArrayList和LinkedList不能,因爲這兩者沒有指定容量的構造函數。

如果你想堅持ArrayList/LinkedList,一個簡單的解決方案是每次手動檢查大小。

public void fixedAdd(List<Integer> list, int val, int size) { 
    list.add(val); 
    if(list.size() > size) list.remove(0); 
} 

在這種情況下LinkedList比ArrayList好。假設有許多要添加的值,但列表大小非常小,將會有很多刪除操作。原因是從ArrayList中刪除的代價是O(N),但對於LinkedList只有O(1)。