2013-06-02 38 views
14

Có trường hợp sử dụng cho phương thức size() trên lớp java.util.BitSet không?Lý do cho phương thức size() của BitSet là gì?

Ý tôi là - JavaDoc cho biết rõ ràng nó phụ thuộc vào triển khai thực hiện, nó trả về kích thước của bộ nhớ trong long[] trong bit. Từ những gì nó nói, người ta có thể kết luận rằng bạn sẽ không thể để thiết lập một chút với chỉ số cao hơn size(), nhưng đó là không đúng sự thật, các BitSet có thể phát triển tự động:

BitSet myBitSet = new BitSet(); 
System.out.println(myBitSet.size()); // prints "64" 
myBitSet.set(768); 
System.out.println(myBitSet.size()); // prints "832" 

Trong mỗi cuộc gặp gỡ duy nhất với BitSet tôi đã có trong cuộc sống của tôi, tôi luôn luôn muốn sử dụng length() vì đó một trả về kích thước hợp lý của BitSet:

BitSet myBitSet = new BitSet(); 
System.out.println(myBitSet.length()); // prints "0" 
myBitSet.set(768); 
System.out.println(myBitSet.length()); // prints "769" 

Mặc dù tôi đã được lập trình Java trong 6 năm trở lại đây, hai phương pháp là luôn luôn đánh giá cao gây nhầm lẫn cho tôi. Tôi thường trộn chúng lại và sử dụng sai một cách ngẫu nhiên, bởi vì trong đầu của tôi, tôi nghĩ về BitSet là một thông minh Set<boolean> nơi tôi muốn sử dụng size().

Giống như nếu ArrayListlength() trả về số lượng phần tử và size() trả lại kích thước của mảng cơ bản.

Hiện tại, có bất kỳ trường hợp sử dụng nào cho phương pháp size() tôi bị thiếu không? Nó có hữu ích trong bất kỳ cách nào? Có ai từng sử dụng nó cho bất cứ điều gì? Nó có thể là quan trọng đối với một số twiddling bit bằng tay hoặc một cái gì đó tương tự?


EDIT (sau khi một số nghiên cứu nhiều hơn nữa)

tôi nhận ra BitSet đã được giới thiệu trong Java 1.0 trong khi khuôn khổ với hầu hết các lớp học chúng tôi sử dụng bộ sưu tập được giới thiệu trong Java 1.2. Vì vậy, về cơ bản có vẻ như với tôi rằng size() được lưu giữ vì lý do cũ và không có sử dụng thực sự cho nó. Các lớp Collection mới không có các phương thức như vậy, trong khi một số các phương thức cũ (ví dụ: Vector) làm.

Trả lời

4

Tôi nhận ra BitSet đã được giới thiệu trong Java 1.0 trong khi khung Collections với hầu hết các lớp chúng tôi sử dụng đã được giới thiệu trong Java 1.2.

Đúng.

Vì vậy, về cơ bản dường như với tôi rằng kích thước() được lưu giữ vì lý do cũ và không có sử dụng thực sự cho nó.

Có, khá nhiều.

Phương thức "kích thước" khác là length() cung cấp cho bạn chỉ mục lớn nhất mà bit được đặt. Từ góc độ hợp lý, length() hữu ích hơn size() ... nhưng length() chỉ được giới thiệu trong Java 1.2.

duy nhất (giả thuyết) sử dụng hợp cụ thể tôi có thể nghĩ về nơi size() có thể là tốt hơn so với length() là khi:

  • bạn đang cố gắng thiết lập một "hàng rào bài" cho một lần lặp lại của các bit trong và
  • rất có khả năng bạn sẽ dừng lặp lại trước khi kết thúc và
  • không quan trọng là bạn đi xa hơn một chút so với bit cuối cùng được đặt.

Trong trường hợp đó, size() được cho là tốt hơn length() vì đây là cuộc gọi rẻ hơn. (Nhìn vào mã nguồn ...) Nhưng đó là khá biên.

(tôi đoán, một use-case dọc theo các đường tương tự là khi bạn đang tạo ra một mới BitSet và preallocating nó dựa trên size() của một hiện BitSet. Một lần nữa, sự khác biệt là biên.)

Nhưng bạn đúng về tính tương thích. Rõ ràng là họ không thể loại bỏ size() hoặc thay đổi ngữ nghĩa của nó mà không tạo ra các vấn đề tương thích. Vì vậy, họ có lẽ đã quyết định để nó một mình. (Thật vậy, họ thậm chí không thấy cần thiết phải từ bỏ nó. "Hại" trong việc có một phương pháp không đặc biệt hữu ích trong API là tối thiểu.)

+0

Dường như tôi đã đi đúng hướng. Tôi sẽ đợi thêm một chút nếu có ai đó sử dụng cách mạng cho phương pháp này, nhưng tôi đoán dấu tích sẽ là của bạn. Đó là một sự xấu hổ họ đã không từ chối nó. Nó sẽ giúp tôi tiết kiệm thời gian quý báu khi sử dụng sai. –

0

Đó là số 0 và 1 mà phải là bội số của 64. Bạn có thể sử dụng số lượng thẻ() cho số 1s.

+2

Tôi biết nó làm gì. Nhưng tôi tự hỏi tại sao ai đó lại muốn gọi một phương pháp như vậy. Hoặc bao gồm nó trong API, ngay từ đầu. Tôi có đúng với giả định của tôi về 'BitSet' là một thế hệ cũ của các lớp util? (Xem chỉnh sửa của tôi) –

+0

Nó không phải là 'số 0 và số 1'. Đó là [ "số bit của không gian thực sự được sử dụng bởi BitSet này để đại diện cho các giá trị chút"] (http://docs.oracle.com/javase/7/docs/api/java/util/BitSet.html#size()). – EJP

+1

@EJP Trong khi đó có thể là rõ ràng hơn, không thấy sự khác biệt. Có không gian không được lấp đầy bằng 0 và 1 không? –

1

Nếu phương pháp size không được thiết kế bởi người tạo Java là công khai, nó chắc chắn sẽ tồn tại như một phương thức/trường riêng. Vì vậy, chúng tôi đang thảo luận về khả năng truy cập của nó và có thể đặt tên.

Java 1.0 lấy rất nhiều cảm hứng, không chỉ cú pháp thủ tục, từ C/C++. Trong thư viện chuẩn C++, các đối tác của BitSet 's lengthsize cũng tồn tại. Chúng được gọi là lần lượt là sizecapacity. Có rất ít lý do khó để sử dụng capacity trong C++, và thậm chí ít hơn trong một ngôn ngữ thu thập rác như Java, nhưng việc tiếp cận phương thức vẫn có thể hữu ích. Tôi sẽ giải thích bằng thuật ngữ Java.

Hãy cho tôi biết số lượng lệnh máy tối đa cần thiết để thực hiện thao tác BitSet như set là bao nhiêu? Người ta muốn trả lời "chỉ là một số ít", nhưng điều này chỉ đúng nếu hoạt động cụ thể đó không dẫn đến tái phân bổ toàn bộ mảng cơ bản. Về mặt lý thuyết, các phân bổ lại biến một thuật toán thời gian không đổi thành một thời gian tuyến tính một.

Sự khác biệt lý thuyết này có tác động thực tế nhiều không? Ít khi. Mảng thường không phát triển quá thường xuyên. Tuy nhiên, bất cứ khi nào bạn có thuật toán hoạt động trên một số phát triển dần dần BitSet với kích thước cuối cùng đã biết, bạn sẽ lưu trên các phân bổ lại nếu bạn vượt qua kích thước cuối cùng đã đến phương thức khởi tạo của BitSet. Trong một số trường hợp rất đặc biệt, điều này thậm chí có thể có tác dụng đáng chú ý, trong hầu hết các trường hợp, nó không bị tổn thương.

  • set sau đó có độ phức tạp về thời gian liên tục - gọi nó không bao giờ có thể chặn ứng dụng quá lâu.
  • nếu chỉ một trường hợp cực lớn BitSet đang sử dụng hết bộ nhớ khả dụng của bạn (theo thiết kế), việc hoán đổi có thể bắt đầu đáng chú ý sau đó phụ thuộc vào cách JVM của bạn thực hiện hoạt động tăng trưởng (có hoặc không có bản sao bổ sung).

Bây giờ hãy tưởng tượng rằng bạn hoạt động trên nhiều BitSets, tất cả đều được phân bổ với kích thước mục tiêu. Bạn đang xây dựng một ví dụ BitSet từ khác và bạn muốn cái mới chia sẻ kích thước mục tiêu cũ như bạn biết bạn sẽ sử dụng chúng cạnh nhau. Có phương thức công khai size giúp việc triển khai này dễ dàng hơn.

0

Một trong những lý do chính tôi nghĩ rằng nó có thể hữu ích là khi chúng ta cần phải mở rộng các lớp BitSet và ghi đè lên các phương pháp chiều dài. Trong trường hợp đó, kích thước là hữu ích. dưới đây là độ dài trả về giá trị với sự phụ thuộc vào phương pháp kích thước.

protected Set bitset; 
public int length() { 
    int returnValue = 0; 
    // Make sure set not empty 
    // Get maximum value +1 
    if (bitset.size() > 0) { 
    Integer max = (Integer)Collections.max(bitset); 
    returnValue = max.intValue()+1; 
    } 
    return returnValue; 
} 
Các vấn đề liên quan