2012-01-23 37 views
8

Vì thư viện lõi Java không có bộ sưu tập như vậy, liệu một mảng có phải là lựa chọn tốt nhất, đặc biệt nếu một người không muốn dựa vào các thư viện của bên thứ ba?Làm cách nào để triển khai "danh sách" kích thước cố định trong Java?

+0

Bạn muốn hành vi nào khi bạn cố thêm mục vào danh sách đầy đủ? Bạn có lẽ cũng nên có một phương pháp kiểm tra nếu có một số không gian. – toto2

+2

Arrays.asList hiện _exactly_ mục này. –

+0

Câu hỏi không rõ ràng: danh sách có được sửa không? hoặc kích thước của nó là cố định? – toto2

Trả lời

4

Tôi muốn viết một lớp bao bọc xung quanh một ArrayList và trong các phương thức addaddAll, tôi sẽ kiểm tra kích thước của danh sách trước khi thêm phần tử mới. Nếu bạn đã đạt đến kích thước tối đa, bạn có thể ném một ngoại lệ (hoặc không làm gì, tùy thuộc vào những gì bạn thực sự muốn làm trong mã của bạn).

Dưới đây là một ví dụ nhỏ:

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

Bạn có thể sử dụng một mảng hoặc ArrayList<E> được khởi tạo trước với kích thước mong muốn.

Nếu bạn muốn chủ động ngăn chặn việc mở rộng danh sách, thì việc sử dụng mảng có lẽ là dễ nhất.

+1

Nhưng nếu tôi thêm một đối tượng vào thể hiện 'ArrayList' sẽ làm cho nó vượt quá kích thước của nó, nó sẽ không tự động mở rộng? – mre

+0

@mre, đúng vậy. – Tudor

+0

@mre: Nếu bạn làm, nó sẽ. Bạn đang nói rằng bạn muốn chủ động ngăn cản mình làm điều này? – 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

Vì vậy, nếu tôi cố gắng để thêm một đối tượng để 'fixedList' mà đã có 10 đối tượng, nó sẽ ném một ngoại lệ hoặc chỉ âm thầm không? – mre

+4

thêm sẽ cung cấp cho bạn UnsupportedOperationException, bạn chỉ có thể sử dụng thiết lập và nhận, về cơ bản hoạt động như một mảng. –

2

Vâng, bạn có thể kế thừa từ lớp ArrayList ví dụ và reimplement phương pháp add để không thể để thêm qua một số tiền nhất định của các yếu tố. Hoặc, thậm chí tốt hơn khi con trỏ ra bởi Laf, sử dụng bố cục:

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

Đó là loại nơi tôi nghĩ tôi sẽ phải đi nếu tôi không muốn sử dụng một mảng. – mre

+5

Tôi sẽ không khuyên bạn nên thừa kế trong trường hợp này, nhưng một lớp wrapper. Việc ghi đè phương thức 'add' có thể tạo ra nhiều vấn đề hơn, bởi vì bạn trở nên phụ thuộc vào việc thực thi' ArrayList'. Đây là điều mà Josh Bloch đề cập trong cuốn sách Java_Effective của anh ấy. – Laf

+0

@mre: Tôi đã đăng một ví dụ. – Tudor

3

Chỉ cần thực hiện của riêng bạn. Bạn có thể sử dụng phương pháp dựa trên proxy. Xác định danh sách của riêng bạn được hỗ trợ bởi ArrayList. Đặt danh sách nội bộ ở chế độ riêng tư. Cũng thực hiện một trường đơn giản limit có mặc định và cũng có thể được đặt thông qua một hàm tạo.

Danh sách của bạn sẽ triển khai List và cho mọi phương pháp sửa đổi danh sách nội bộ, tăng và giảm số lượng phù hợp. Nếu kích thước vượt quá giới hạn, hãy ném một số loại ngoại lệ. Một cái gì đó như

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

Bạn sẽ phải làm việc trên generics, và nhớ hỗ trợ các trường hợp nhiều thứ được thêm cùng một lúc addAll.

+0

Vì vậy, chúng ta lấy một 'ArrayList' đã được triển khai để cho phép chúng ta mở rộng kích thước của mảng động và sau đó thay đổi hành vi của nó để chúng ta không thể làm điều đó nữa? Vâng vâng 'không phải x' cũng giống như' x', nhưng điều đó khá vô nghĩa phải không? – Voo

+0

Tôi không chắc điểm của bạn là gì. Bạn có nói rằng danh sách tùy chỉnh của mình nên được hỗ trợ bởi một mảng thay thế? – hvgotcodes

+0

Vâng, bạn đã loại bỏ tất cả các chức năng bổ sung mà 'ArrayList' được thêm vào trên một mảng đơn giản, vì vậy chúng ta có thể sử dụng chính mảng đó - hoặc nếu chúng ta cần thêm hàm và đồng nghĩa, chỉ cần sao lưu nó bằng một mảng sẽ đơn giản hơn. – Voo

0

Sử dụng Collections.unmodifiableList(List<T> list). Điều này sẽ trả về một đối tượng List<T> chung mà ném UnsupportedOperationException nếu bạn cố gắng thêm (hoặc loại bỏ) các phần tử.

0

Tôi có thể sẽ bị đốt cháy, nhưng bạn cũng có thể sử dụng số ArrayBlockingQueue cho việc này. Điều này mang lại lợi ích khi có thể sử dụng các phương pháp Bộ sưu tập thông thường.

+0

Nó không cung cấp quyền truy cập vào tất cả các phương thức danh sách (mặc dù nó không thực hiện bất kỳ loại danh sách nào) - đặc biệt là các phương pháp truy cập dựa trên chỉ mục, mà (cho tôi) sẽ là lý do chính để sử dụng danh sách ở nơi đầu tiên. –

+0

Đúng, tôi đã cập nhật câu trả lời của mình để phản ánh rằng nó thực sự triển khai các hoạt động Thu thập, chứ không phải Danh sách. – 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");     

     }   
Các vấn đề liên quan