2012-01-23 123 views
8

Dado que la biblioteca central de Java no tiene dicha colección, ¿una matriz sería la mejor opción, especialmente si uno no desea confiar en bibliotecas de terceros?¿Cómo implementar una "lista" de tamaño fijo en Java?

+0

¿Qué comportamiento desea cuando intenta agregar un artículo a una lista completa? Probablemente también deberías tener un método que verifique si hay espacio. – toto2

+2

Arrays.asList hace _exactly_ esto. –

+0

La pregunta es ambigua: ¿la lista es fija? o su tamaño es fijo? – toto2

Respuesta

4

Escribía una clase contenedora alrededor de un ArrayList, y en los métodos add y addAll, buscaba el tamaño de la lista antes de agregar nuevos elementos. Si ha alcanzado el tamaño máximo, puede lanzar una excepción (o no hacer nada, dependiendo de lo que realmente quiera hacer en su código).

Aquí hay un pequeño ejemplo:

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

Puede usar una matriz o ArrayList<E> preinicializada con el tamaño deseado.

Si desea activamente evitar la expansión de la lista, y luego usar una matriz es probablemente la más fácil.

+1

Pero si agrego un objeto a la instancia 'ArrayList' que causaría que excediera su tamaño, ¿no se expandirá automáticamente? – mre

+0

@mre, sí lo hará. – Tudor

+0

@mre: si lo hace, lo hará. ¿Estás diciendo que quieres evitar activamente que lo hagas? – 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

Entonces, si intento agregar otro objeto a 'fixedList' que ya contiene 10 objetos, ¿arrojará una excepción o simplemente fallará en silencio? – mre

+4

add le dará UnsupportedOperationException, usted solo puede usar set y get, básicamente se comporta como una matriz. –

2

Bien se podría heredar de la clase ArrayList por ejemplo y reimplementar el método add a no ser capaz de añadir más allá de una determinada cantidad de elementos. O, incluso mejor como puntero por Laf, use la composición:

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

Eso es algo de lo que estaba pensando que tendría que ir si no quería usar una matriz. – mre

+5

No recomendaría la herencia en este caso, sino una clase contenedora. Anular el método 'add' podría crear más problemas, porque te vuelves dependiente de la implementación' ArrayList'. Esto es algo que Josh Bloch menciona en su libro _Effective Java_. – Laf

+0

@mre: He publicado un ejemplo. – Tudor

3

Simplemente implemente la suya. Podría usar un enfoque basado en proxy. Defina su propia lista respaldada por ArrayList. Haga que la lista interna sea privada. También implemente un campo simple limit que tiene un valor predeterminado y también se puede establecer a través de un constructor.

Su lista implementará List, y para cada método que modifique la lista interna, incremente y disminuya el conteo de manera apropiada. Si el tamaño excede el límite, lanza algún tipo de excepción. Algo así como

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); 
    } 
    ... 
} 

Tendrá que trabajar en los genéricos, y recordar a apoyar a los casos en los que se añaden múltiples cosas a la vez addAll.

+0

Así que tomamos una 'ArrayList' que se implementó para permitirnos ampliar el tamaño de las matrices de forma dinámica y luego cambiar su comportamiento para que no podamos seguir haciéndolo. Bueno, sí, 'no no x' es lo mismo que' x', pero eso no tiene sentido, ¿no? – Voo

+0

No estoy seguro de cuál es su punto. ¿Estás diciendo que su lista personalizada debería estar respaldada por una matriz en su lugar? – hvgotcodes

+0

Bueno, eliminaste toda la funcionalidad adicional que 'ArrayList' agregaba sobre una matriz simple, así que solo podíamos usar la matriz en sí misma, o si necesitamos las funciones de agregar y compartir, sí solo una copia de seguridad de una matriz sería más simple también. – Voo

0

Uso Collections.unmodifiableList(List<T> list). Esto devolverá un objeto genérico List<T> que arroja UnsupportedOperationException si intenta agregar (o eliminar) elementos.

0

Probablemente me queme, pero también puede usar un ArrayBlockingQueue para esto. Lo que proporciona la ventaja de poder utilizar los métodos Colección regulares.

+0

Sin embargo, no ofrece acceso a * todos los métodos de la lista (es decir, no implementa ningún tipo de lista), particularmente métodos de acceso basados ​​en índices, que (para mí de todos modos) sería la razón principal para usar un lista en primer lugar. –

+0

Es cierto, actualicé mi respuesta para reflejar que realmente implementa las operaciones de recolección, no la lista. – 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");     

     }   
Cuestiones relacionadas