63

I'm looking for a good Java BitSet example to work with 0 and 1s. I tried looking at the Javadocs but I don't understand the usage of the class by just reading that. For instance, how would the and, or, and xor methods work on two different BitSet objects?

For example:

  BitSet bits1 = new BitSet();
  BitSet bits2 = new BitSet();

  bits2.set(1000001);
  bits1.set(1111111);

  bits2.and(bits1);

  System.out.println(bits2);

If I do this it returns bits2 as empty why is that?

mdewitt
  • 2,526
  • 19
  • 23
Steffan Harris
  • 9,106
  • 30
  • 75
  • 101
  • 2
    http://en.wikipedia.org/wiki/Bitwise_operation - they work exactly the same as they would if you were using `& | ^` etc. with a primitive numeric type. – Brian Roach Feb 17 '12 at 18:49
  • What, specifically, don't you understand? You create a BitSet and then call functions on it, such as `.and`, `.or` and `.xor`. Each of these functions takes as a parameter another BitSet object. – Tony Feb 17 '12 at 18:51
  • Well, i tried to do an `and` on the example above and the bitset became empty. – Steffan Harris Feb 17 '12 at 18:58

7 Answers7

113

For the specific problem you mentioned: when you called bits2.set(1000001), you set the one millionth and first bit to true. Then when you intersected with bits1, which had the one million, 111 thousand, and 111st bit set, they had no bits in common.

I think what you meant to do was

 bits2.set(0); // set the 0th bit
 bits2.set(6); // set the 6th bit

Does this help clear things up?

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • "they had no bits in common" how are you saying this ?because I see first and last bits of bits1 and bits2 are common right ?still am not understood why bits2 became empty. Could you please explain me some more briefly. – JAVA Sep 11 '18 at 13:28
  • 6
    @JAVA I don't know how to explain any more clearly than that bits1 has only one bit set to true, which is the bit at index one million and one (the number 1,000,001), and bits2 has only one bit set to true, the bit at index one million one hundred eleven thousand and one hundred eleven (1,111,111). – Louis Wasserman Sep 11 '18 at 15:09
60

If you want to work with bits you can use int values in Java 7.

int bits2 = 0b1000001;
int bits1 = 0b1111111;
bits2 &= bits1;
System.out.println(Integer.toBinaryString(bits2));

prints

1000001
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 1
    when you save them as `ints` are they taking `4 byte` or `7 bits`? – daydreamer Oct 20 '15 at 21:39
  • 2
    @daydreamer Looking at the [source code](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/BitSet.java) shows that a `BitSet` is implemented behind the scenes as a `long[]`. "The ith bit is stored in bits[i/64] at bit position i % 64 (where bit position 0 refers to the least significant bit and 63 refers to the most significant bit)." So at minimum, any BitSet will use 64 bits. Even the parametrized constructor says "Creates a bit set whose initial size is **large enough** to explicitly represent bits with indices in the range..." – mbomb007 Jun 16 '16 at 14:05
48

BitSet doesn't have convenience methods for accepting strings of bits like that. I've provided some below, and now the example works as you'd expect. Note that this uses functionality new in Java 7; it's easy to find implementations of these methods online if you'd like to use Java 6.

import java.util.BitSet;

class Scratch {
    public static void main(String[] args) {
        BitSet bits1 = fromString("1000001");
        BitSet bits2 = fromString("1111111");

        System.out.println(toString(bits1)); // prints 1000001
        System.out.println(toString(bits2)); // prints 1111111

        bits2.and(bits1);

        System.out.println(toString(bits2)); // prints 1000001
    }

    private static BitSet fromString(final String s) {
        return BitSet.valueOf(new long[] { Long.parseLong(s, 2) });
    }

    private static String toString(BitSet bs) {
        return Long.toString(bs.toLongArray()[0], 2);
    }
}
orlandocr
  • 313
  • 2
  • 8
FauxFaux
  • 2,445
  • 16
  • 20
  • 1
    Perfect! I liked your `toString(BitSet bs)` method. Very useful! You could invert the bits to put bit_0 on the right. – Magno C Feb 11 '15 at 12:23
  • This is the best answer because it understood the OPs confusion (and mine!) and cut straight to the chase. – kellyfj Jan 21 '20 at 21:25
8

Here are some links about bitSet that would help you:

UPDATE:

In the docs, it is said:

public void set(int bitIndex)

Sets the bit at the specified index to true.

So when you call bits2.set(10);, it is considered as 10 decimal not 1 0 so what you get is the following number 1000000000.

To set it correctly, in this example, I want to set the 2nd bit to 1, so I call bits2.set(1); because the index starts at 0.

In conclusion, for every bit set to 1, you need to call bitSet.Set and provide it with the index of the bit.

Adel Boutros
  • 10,205
  • 7
  • 55
  • 89
6

I am sharing my implementation for creating a BitSet object using string of bits as input.

private static BitSet createFromString(String s) {
    BitSet t = new BitSet(s.length());
    int lastBitIndex = s.length() - 1;

    for (int i = lastBitIndex; i >= 0; i--) {
        if ( s.charAt(i) == '1'){
            t.set(lastBitIndex - i);                            
        }               
    }

    return t;
}

For string input "1001"

BitSet s1 = createFromString("1001");
    System.out.println(s1);

output :

{0, 3}
Aditya Gaykar
  • 470
  • 1
  • 5
  • 10
0

Try this:

import java.util.BitSet;

public class BitSetExample {

    public static void main(String args[]){
        BitSet bits1 = new BitSet(7);
        BitSet bits2 = new BitSet(7);

        // set some bits
        for(int i = 0; i < 7; i++) {
            if((i % 2) == 0) bits1.set(i);
            if((i % 3) != 0) bits2.set(i);
        }

        System.out.println("BitSet1: ");

        for(int i = 0; i < 7; i++) {
            System.out.print(bits1.get(i)? "1 ": "0 ");
        }

        System.out.println("\nBitSet2: ");

        for(int i = 0; i < 7; i++) {
            System.out.print(bits2.get(i)? "1 ": "0 ");
        }

        System.out.println();

        //And
        bits1.and(bits2);

        System.out.println("b1 = b1 AND b2\nBitSet1: ");

        for(int i = 0; i < 7; i++) {
            System.out.print(bits1.get(i)? "1 ": "0 ");
        }

        System.out.println();
        System.out.println("BitSet2: ");

        for(int i = 0; i < 7; i++) {
            System.out.print(bits2.get(i)? "1 ": "0 ");
        }

        System.out.println();

        //Or
        bits1.or(bits2);

        System.out.println("b1 = b1 OR b2\nBitSet1: ");

        for(int i = 0; i < 7; i++) {
            System.out.print(bits1.get(i)? "1 ": "0 ");
        }

        System.out.println();
        System.out.println("BitSet2: ");

        for(int i = 0; i < 7; i++) {
            System.out.print(bits2.get(i)? "1 ": "0 ");
        }

        System.out.println();

        //Xor
        bits1.xor(bits2);

        System.out.println("b1 = b1 XOR b2\nBitSet1: ");

        for(int i = 0; i < 7; i++) {
            System.out.print(bits1.get(i)? "1 ": "0 ");
        }

        System.out.println();
        System.out.println("BitSet2: ");

        for(int i = 0; i < 7; i++) {
            System.out.print(bits2.get(i)? "1 ": "0 ");
        }

        System.out.println();

        //Setting bits to zero and one
        bits1.set(1);
        bits2.set(1,false);

        System.out.println("set bit 1 of BitSet1 to one and set bit 1 of BitSet2 to zero\nBitSet1: ");

        for(int i = 0; i < 7; i++) {
            System.out.print(bits1.get(i)? "1 ": "0 ");
        }

        System.out.println();
        System.out.println("BitSet2: ");

        for(int i = 0; i < 7; i++) {
            System.out.print(bits2.get(i)? "1 ": "0 ");
        }

        System.out.println();

    }
}

I hope this is useful. For more information, please visit: https://github.com/m-vahidalizadeh/foundations/blob/master/src/data_structures/BitSetExample.java.

Mohammad
  • 6,024
  • 3
  • 22
  • 30
0

In case you also need to work with bit addresses longer than Integer.MAX_VALUE I modified java.util.BitSet (here: LongBitSet) to accept long inputs in get and set methods. I did it to fully use memory for a prime sieve experiment.

juanmf
  • 2,002
  • 2
  • 26
  • 28