2010-08-25 37 views

Trả lời

18

Không, bạn không thể! Java ArrayList không cung cấp một cách để truy cập khả năng hiện tại của nó.

Bạn chỉ có thể xây dựng một ArrayList xác định dung lượng ban đầu bằng cách sử dụng hàm tạo ArrayList(int initialCapacity) hoặc tăng dung lượng bằng cách gọi ensureCapacity().

+6

"Không, bạn không thể." Một dấu ấn sẽ làm cho điều này trở nên vui nhộn. –

+1

@klez là bây giờ :)? – Gopi

+2

Bây giờ bạn nhận được upvote của tôi thưa ông! –

1

Bạn không cần phải lo lắng về dung lượng, đó là chi tiết triển khai nội bộ. Nếu mảng nội bộ đầy, thì nó sẽ mở rộng. Bạn có thể tìm hiểu có bao nhiêu phần tử hiện có trong ArrayList của bạn với phương thức size().

1

Từ đặc điểm kỹ thuật: "Dung lượng là kích thước của mảng được sử dụng để lưu trữ các phần tử trong danh sách. Nó luôn có kích thước danh sách lớn nhất. Do các phần tử được thêm vào ArrayList, khả năng của nó sẽ tự động tăng lên Các chi tiết của chính sách tăng trưởng không được chỉ rõ ngoài việc thêm một phần tử có chi phí thời gian khấu hao không đổi. "

Vì vậy, không có cách nào để biết dung lượng hiện tại là gì và cũng không phát triển như thế nào.

0

Bạn có cần điều này trong thời gian chạy hoặc có được chấp nhận khi thực hiện kiểm tra không? Nếu thử nghiệm của nó, bạn thường có thể thấy dung lượng sử dụng trình gỡ lỗi IDE yêu thích của bạn. Tôi không có số chính xác, nhưng 1.7 thường là kích thước tăng trưởng dung lượng. Vì vậy, nếu bạn tạo một arraylist với 10 mục, java sẽ làm cho nó kích thước 17.

0

API không cung cấp nó. Trong nội bộ, công suất được nhân với một yếu tố bất cứ khi nào thêm (..) được gọi là trong khi hết công suất. Tuy nhiên, đặc tả Java không nói bất cứ điều gì về yếu tố không đổi này ... Việc triển khai của Sun sử dụng hệ số 1.5, vì vậy bạn có giới hạn trên là 1.5 * size() cho dung lượng.

Hãy nhớ rằng bạn có thể sử dụng trimToSize() để "nhỏ gọn" danh sách và làm cho dung lượng bằng với kích thước().

10

ArrayListtrừu tượng để tự động phát triển List yếu tố. Bạn hiếm khi cần biết khả năng của nó. Hãy xem xét Phiên bản Java hiệu quả thứ 2, Mục 52: Tham khảo các đối tượng theo giao diện của chúng. Thực tế, bạn thậm chí không nên quan tâm nếu đó là ArrayList hoặc LinkedList; nó chỉ là List.

Điều đó nói rằng, những phương pháp này có thể quan tâm đến bạn:

  • ArrayList(int initialCapacity)
    • Tạo thời danh sách trống với công suất ban đầu theo quy định.
  • void ensureCapacity(int minCapacity)
    • Tăng công suất ArrayList trường hợp này, nếu cần thiết, để đảm bảo rằng nó có thể nắm giữ ít nhất số lượng các yếu tố xác định bởi các tham số công suất tối thiểu.
  • void trimToSize()
    • tính kỹ thuật cao năng lực của ArrayList trường hợp này là kích thước hiện tại của danh sách. Một ứng dụng có thể sử dụng thao tác này để giảm thiểu dung lượng lưu trữ của một cá thể ArrayList.
+0

Tôi nghĩ rằng từ của Bloch về điều này là dứt khoát. – ncmathsadist

63

Tôi tò mò, bạn cần nó để làm gì? Bạn nên biết rằng công suất không phải là (có thể âm thanh) giới hạn trên của số lượng bạn có thể đưa vào ArrayList. Đó là một giá trị thể hiện số lượng dữ liệu bạn có thể đưa vào danh sách, mà không buộc nó phải phân bổ lại mảng nội bộ. Về cơ bản, khái niệm về năng lực chỉ có ở đó để bạn có thể tinh chỉnh hiệu suất một chút.

Dù sao, có lẽ bạn đã biết điều đó, do đó, ở đây có câu trả lời thực tế.

Giao diện được API cung cấp cho ArrayList chỉ đơn giản là không hỗ trợ trường hợp sử dụng như vậy. Có nhiều lý do cho việc này. Một lý do là bạn không nên quan tâm đến điều này. ArrayList được coi là một mảng không bị ràng buộc, không tóm tắt các chi tiết như dung lượng.

Gần nhất bạn có thể kiểm soát dung lượng là thông qua hàm tạo ArrayList(int initialCapacity) và hai phương thức trimToSize()ensureCapacity(int minCapacity).

Đối với niềm vui tuy nhiên, tôi quản lý để giải quyết nó thông qua một xấu xí phản ánh-Hack (không sử dụng này):

import java.lang.reflect.Field; 
import java.util.ArrayList; 
public class Test { 

    public static void main(String[] args) throws Exception { 
     ArrayList<Integer> list = new ArrayList<Integer>(3); 
     for (int i = 0; i < 17; i++) { 
      list.add(i); 
      System.out.format("Size: %2d, Capacity: %2d%n", 
           list.size(), getCapacity(list)); 
     } 
    } 

    static int getCapacity(ArrayList<?> l) throws Exception { 
     Field dataField = ArrayList.class.getDeclaredField("elementData"); 
     dataField.setAccessible(true); 
     return ((Object[]) dataField.get(l)).length; 
    } 
} 

Output:

Size: 1, Capacity: 3 
Size: 2, Capacity: 3 
Size: 3, Capacity: 3 
Size: 4, Capacity: 5 
Size: 5, Capacity: 5 
Size: 6, Capacity: 8 
Size: 7, Capacity: 8 
Size: 8, Capacity: 8 
Size: 9, Capacity: 13 
Size: 10, Capacity: 13 
Size: 11, Capacity: 13 
Size: 12, Capacity: 13 
Size: 13, Capacity: 13 
Size: 14, Capacity: 20 
Size: 15, Capacity: 20 
Size: 16, Capacity: 20 
Size: 17, Capacity: 20 
+3

Tôi bị cám dỗ bỏ phiếu này xuống, ngay cả 'mặc dù nó là chính xác, chuyên sâu và cảnh báo về những nguy hiểm của việc cố gắng phá vỡ nó, chỉ vì nó cung cấp mã cho hack xấu xí ... –

+16

Chắc chắn, cần nhấn mạnh rằng phương pháp này không nên được sử dụng trong mã sản xuất. Nó * có thể * tuy nhiên là trường hợp ai đó muốn, ví dụ, gỡ lỗi một số vấn đề hiệu suất hoặc tương tự, trong trường hợp đoạn mã trên có thể hữu ích. Nhưng như tôi đã viết trong câu trả lời, tôi thực hiện nó cho vui và nó không thực sự được sử dụng trong 99% các trường hợp. – aioobe

+0

@aiobee hack đẹp :) Để làm cho câu trả lời của bạn hoàn chỉnh hơn, tôi sẽ đề nghị bạn cũng đề cập đến java sdk/jvm bạn đã sử dụng. Kể từ khi làm việc thành công này sẽ được dựa trên việc thực hiện nền tảng java bạn đang sử dụng. – Gopi

1

Tôi đi theo xu hướng ở đây ... người dùng có câu hỏi mặc dù không có ngữ cảnh. Nếu không có bối cảnh, biết khả năng không cần thiết vì mảng sao lưu sẽ phát triển để phù hợp ...

Bạn có thể làm như sau để biết chắc chắn khả năng của bạn với ArrayList của bạn. Tác dụng phụ là mảng sao lưu sẽ được cắt thành số phần tử chính xác trong mảng:

ArrayList list = new ArrayList(); 
//add a bunch of elements 
list.trimToSize(); 
System.out.println("Capacity = " + list.size()); 

Tận hưởng!

+1

Trong ArrayList phương thức size() trả về số lượng các phần tử (các đối tượng) có trong danh sách không phải là dung lượng. – subhashis

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