2012-01-23 49 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");     

     }