2010-05-18 47 views
7

Tôi có thiếu thứ gì đó rõ ràng không? Hay không ai trên thế giới thực sự sử dụng java.util.BitSet?java.util.BitSet - set() không hoạt động như mong đợi

Các thử nghiệm sau thất bại:

@Test 
public void testBitSet() throws Exception { 
    BitSet b = new BitSet(); 
    b.set(0, true); 
    b.set(1, false); 
    assertEquals(2, b.length()); 
} 

Nó thực sự không rõ ràng với tôi tại sao tôi không kết thúc với một BitSet chiều dài 2 và giá trị 10. Tôi lén nhìn tại nguồn cho java.util.BitSet , và về kiểm tra ngẫu nhiên, có vẻ như không phân biệt đủ giữa một chút đã được đặt sai và một chút chưa bao giờ được đặt thành bất kỳ giá trị nào ...

(Lưu ý rằng thiết lập rõ ràng kích thước của BitSet trong hàm tạo không có hiệu lực, ví dụ:

BitSet b = new BitSet(2); 
+1

"Hay chỉ không ai trên thế giới thực sự sử dụng java.util. BitSet? " ... yea, phải, kéo cái kia - nó có chuông trên đó! –

+0

@Stephen cái nào khác? ;-) – denishaskin

+1

nút * khác * khác! –

Trả lời

6

Mọi người sử dụng BitSet; Tuy nhiên, họ sử dụng nó cho một cái gì đó khác với những gì bạn có ý định. Có lẽ tốt nhất là hãy nghĩ đến BitSet là một hình thức rất nhỏ gọn, hiệu quả về bộ nhớ của Set<Integer> có đặc tính riêng mà bạn không thể đặt số âm vào đó.

Nó rất phổ biến với BitSet s sử dụng chúng trong các mô hình của

for (int id = set.nextSetBit(0); id >= 0; id = set.nextSetBit(id + 1)) { 
    // do stuff to a set index 
} 

sau khi bạn làm điều gì đó để lấp đầy chúng. Điều này tương đương với việc lặp qua các phần tử của Set.

+0

Giải thích tốt. Về cơ bản, có vẻ như BitSet không thực sự phù hợp để đại diện cho một bitfield có độ dài cố định (hoặc mảng bit). – denishaskin

+0

Vâng, với độ dài * cố định *, nếu bạn không dựa vào BitSet để duy trì độ dài cho bạn thì không sao. Nếu bạn muốn BitSet xử lý độ dài cho bạn, bạn sẽ thất vọng. –

8

Bạn chút bộ cao nhất (như trong "thiết lập để 1") là Bit 0. Vì vậy, độ dài nên 1.

Xem JavaDoc for length:

public int length()

Trả về "kích thước lôgic" của BitSet này: chỉ mục của bit được đặt cao nhất trong BitSet cộng một. Trả về số không nếu BitSet không chứa bit thiết lập.

Có lẽ bạn đang tìm kiếm size mặc dù nó có thể là có thể cao hơn hơn hai nếu bit được phân bổ ở độ phân giải nhất định (ví dụ 16 bit ranh giới)?

+0

ZZ, tôi đã làm sạch nó để đảm bảo rằng nó đã rõ ràng (và + 1'ed nó), hy vọng bạn không nhớ. Cho rằng tôi ban đầu hiểu lầm "thiết lập" là "đã được thiết lập để bất cứ điều gì", con số thấp hơn cũng có thể có vấn đề đó :-) – paxdiablo

+0

@paxdiablo: Rõ ràng hơn nhiều. Cảm ơn! –

2

Do bitet được sao lưu bởi một [] dài, kích thước tối thiểu là 64 (vì 1 dài là 64 bit). Kích thước được tăng lên bởi một bội số của 64 và vì một lý do nào đó, chúng không duy trì số bit bạn dự định biểu diễn khi bạn sử dụng hàm tạo có một int.

3

Điều này làm tôi bối rối, không chắc chắn về lý do đằng sau chức năng hiện tại khá bất ngờ của BitSet. Tuy nhiên kể từ khi nó không phải là cuối cùng, chúng ta có thể sử dụng một số vòng tay và mở rộng chiến thuật và làm như sau để có được một BitSet cố định với ngữ nghĩa chiều dài như mong đợi:

import java.util.BitSet; 

/** 
* Variation of BitSet which does NOT interpret the highest bit synonymous with 
* its length. 
* 
* @author [email protected] 
*/ 
public class FixedBitSet extends BitSet{ 

    int fixedLength; 

    public FixedBitSet(int fixedLength){ 
     super(fixedLength); 
     this.fixedLength = fixedLength; 
    } 

    @Override 
    public int length() { 
     return fixedLength; 
    } 
} 
0

Tốt Casper! Cải tiến nhỏ của bạn thực sự đã có mặt trong bản gốc của BitSet java def!Tôi cũng đề nghị này (append() và concat() rất hữu ích cho tập quán khác nhau)

import java.util.BitSet; 

public class fixBitSet extends BitSet { 

    public int fsize = 0; 

    public void set(int k, boolean value) { 
    if (k >= fsize) 
     fsize = k + 1; 
    super.set(k, value); 
    } 

    public void append(fixBitSet bs) { 
    for (int k = 0; k < bs.fsize; k++) 
     super.set(fsize + k, bs.get(k)); 
    fsize += bs.fsize; 
    } 

    public static fixBitSet concat(fixBitSet[] vbs) { 
    final fixBitSet bs = new fixBitSet(); 
    for (fixBitSet xbs : vbs) 
     bs.append(xbs); 
    return (bs); 
    } 

} 
1

// Abhay Dandekar

import java.util.BitSet; 

public class TestBitSet { 

    public static void main(String[] args) { 

     BitSet bitSet = new BitSet(); 
     System.out.println("State 0 : " + bitSet.size() + " : " + bitSet.length()); 

     bitSet.set(0, true); 
     bitSet.set(1, true); 
     System.out.println("State 1 : " + bitSet.size() + " : " + bitSet.length()); 

     bitSet.set(2, false); 
     bitSet.set(3, false); 
     System.out.println("State 2 : " + bitSet.size() + " : " + bitSet.length()); 

     bitSet.set(4, true); 
     System.out.println("State 3 : " + bitSet.size() + " : " + bitSet.length()); 

    } 
} 

Một chương trình java đơn giản để hiển thị những gì xảy ra bên trong. Một số điểm cần lưu ý:

  1. BitSet được hỗ trợ bởi một dài

  2. Tất cả các giá trị mặc định là sai

  3. Trong khi trở về chiều dài, nó sẽ trả về chỉ số + 1 trong tổng số cao nhất "true "giá trị trong tập hợp.

Kết quả dưới đây sẽ có thể giải thích bản thân:

State 0 : 64 : 0 

State 1 : 64 : 2 

State 2 : 64 : 2 

State 3 : 64 : 5 

Vì vậy, điểm kết luận:

  1. Không sử dụng độ dài để kết thúc không có các bit sửa đổi

  2. Có thể được sử dụng trong các trường hợp như bộ lọc nở. Thông tin thêm về bộ lọc nở có thể được googled ..;)

Hope this helps

Kính trọng,

Abhay Dandekar

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