2012-01-23 79 views
8

由於Java核心庫沒有這樣的集合,數組是否是最好的選擇,特別是如果不想依賴第三方庫?如何在Java中實現一個固定大小的「列表」?

+0

當您嘗試將項目添加到完整列表時,您想要什麼行爲?你應該也可以有一個方法來檢查是否有空間。 – toto2

+2

Arrays.asList不_exactly_ this。 –

+0

問題不明確:列表已修復?或者它的大小是固定的? – toto2

回答

4

我會寫一個包裝類的ArrayList左右,而在addaddAll方法,我會加入新的元素之前檢查列表的大小。如果你達到了最大尺寸,你可以拋出一個異常(或者什麼也不做,這取決於你真正想在你的代碼中做什麼)。

這裏有一個簡單的例子:

public class SizeLimitedArray<E> implements java.util.List<E> 
    { 
    private static final int DEFAULT_SIZE_LIMIT = 10; 
    private ArrayList<E> myList; 
    private int maxSize; 

    public SizeLimitedArray() 
     { 
     this (DEFAULT_SIZE_LIMIT); 
     } 

    public SizeLimitedArray (int size) 
     { 
     myList = new ArrayList<E> (size); 
     maxSize = size; 
     } 

    @Override 
    public boolean add (E objectToAdd) 
     { 
     if (myList.size() > maxSize) 
      { 
      throw new IllegalStateException ("The array is full"); 
      } 

     return myList.add (objectToAdd); 
     } 

    @Override 
    public boolean addAll (Collection collectionToAdd) 
     { 
     if (myList.size() + collectionToAdd.size() > maxSize) 
      { 
      throw new IllegalStateException ("The array is full"); 
      } 

     return myList.addAll (collectionToAdd); 
     } 

    // Rest of class omitted for brevity 
    } 
5

您可以使用一個數組或預先初始化爲所需大小的數組或ArrayList<E>

如果要積極阻止的列表擴展,那麼使用數組可能是最簡單的。

+1

但是,如果我添加一個對象到'ArrayList'實例會導致它超過它的大小,它會不會自動擴展? – mre

+0

@mre,是的。 – Tudor

+0

@mre:如果你這樣做,它會的。你是說你想積極阻止自己這樣做嗎? – NPE

12

Arrays.asList(T ...)Returns a fixed-size list backed by the specified array

Object[] array = new Object[10]; 
List<Object> fixedList = Arrays.asList(array); 
+1

所以,如果我試圖添加另一個對象到已經包含10個對象的'fixedList',它會拋出一個異常還是隻是默默地失敗? – mre

+4

add會給你UnsupportedOperationException,你只能使用set和get,基本上就像一個數組。 –

2

那麼你可以從例如ArrayList類繼承,並重新實現add方法不能夠添加元素過去的一個給定的量。或者,如Laf指出的那樣更好,請使用組合:

public class MyArrayList<T> { 
    private ArrayList<T> innerList; 
    private int maxSize; 

    public boolean add(T item) { 
     if(innerList.size() < maxSize) { 
      return innerList.add(item); 
     } else { 
      return false; 
     } 
    } 
} 
+0

這就是我認爲如果我不想使用數組就必須去的地方。 – mre

+5

在這種情況下,我不會推薦繼承,而是一個包裝類。重寫'add'方法可能會產生更多的問題,因爲你依賴於ArrayList實現。 Josh Bloch在他的_Effective Java_書中提到了這一點。 – Laf

+0

@mre:我發佈了一個例子。 – Tudor

3

只是實現您自己的。您可以使用基於代理的方法。定義您自己的名單,由ArrayList支持。使內部列表保密。還要實現一個簡單的limit字段,該字段具有默認值,也可以通過構造函數進行設置。

您的列表將執行List,並且對於每個修改內部列表的方法,都適當地增加和減少計數。如果大小超過限制,請拋出某種異常。喜歡的東西

public class FixedList implements List { 
    private ArrayList<E> list = new ArrayList<E>(); 
    private int limit = 10; // default 

    FixedList(){} // default constructor 

    FixedList(int limit) { 
     this.limit = limit; 
    } 

    public boolean add(E object) { 
     if (this.list.size() == limit - 1) { 
      // throw some sort of LimitExceeded Runtime Exception 
     } 

     this.list.add(object); 
    } 
    ... 
} 

您必須對仿製藥的工作,記得要支持在多個事情一次addAll添加的情況。

+0

所以我們採用一個被實現的'ArrayList'來允許我們動態地擴展數組的大小,然後改變它的行爲,所以我們不能再這樣做了?那麼是的'不是x''和'x'是一樣的,但是這沒什麼意義,不是嗎? – Voo

+0

我不確定你的觀點。你是說他的自定義列表應該由數組支持嗎? – hvgotcodes

+0

好吧,你刪除了ArrayList添加到一個簡單數組上的所有附加功能,所以我們可以只使用數組本身 - 或者如果我們需要add和co函數,那麼只是通過數組備份它也會更簡單。 – Voo

0

使用Collections.unmodifiableList(List<T> list)。這將返回一個通用的List<T>對象,如果您嘗試添加(或刪除)元素,則該對象會拋出UnsupportedOperationException

0

我可能會被燒傷,但您也可以使用ArrayBlockingQueue。這提供了能夠使用常規方法的益處。

+0

儘管它不提供對所有列表方法的訪問(即它沒有實現任何列表),特別是基於索引的訪問方法,對於我來說(無論如何)將是使用列表中的第一個地方。 –

+0

確實,我更新了答案以反映它確實實現了收集操作,而不是List。 – Perception

-1
public class libsystem extends javax.swing.JFrame { 

    //public static ArrayList<books> al = new ArrayList<books>(); 
    public static List<books> al = Arrays.asList(new books[100]); 
    public libsystem() { 
    initComponents(); 
    } 
    String msg =jTextArea1.getText(); 

    try { 
     FileWriter fs=new FileWriter("library.txt"); 
     try(
      BufferedWriter out= new BufferedWriter(fs)){; 
      out.write(msg); 
     } 
     } catch (Exception e){ 
     System.err.println("wrong" + e.getMessage());         
    } 
    String line; 
    String id,name,type; 
    try{ 
     FileReader in=new FileReader("library.txt"); 
     try (BufferedReader br = new BufferedReader(in)) {  

      while((line=br.readLine())!=null){  
       StringTokenizer st1 = new StringTokenizer(line,",");  
       while(st1.hasMoreTokens()){  
        id=st1.nextToken();  
        name=st1.nextToken();  
        type=st1.nextToken(); 
     books book=new books(id,name,type);  
       al.add(book);  
       }  
       br.close();  
     for(int i=0;i<al.size();i++){  
     books obj = al.get(i);  

     System.out.println("Book NAme :"+obj.getName()+ "\n" +"          Name:"+obj.getAuthor()+ "\n"+"Type :"+obj.getSubject()+"\n");     

     }