views:

435

answers:

2

What's the best way to unstub the following functions?

// Convert a bit-vector to an integer. 
int bitvec2int(boolean[] b)
{
    [CODE HERE]
}

// Convert an integer x to an n-element bit-vector. 
boolean[] int2bitvec(int x, int n)
{
    [CODE HERE]
}

Or is there a better way to do that sort of thing than passing boolean arrays around?

This comes up in an Android app where we need an array of 20 booleans to persist and the easiest way to do that is to write an integer or string to the key-value store.

I'll post the way we (Bee and I) wrote the above as an answer. Thanks!

+7  A: 

Use java.util.BitSet instead. It'd be much faster than dealing with boolean[].

Also, you should really ask yourself if these 20 boolean really should be enum, in which case you can use EnumSet, which is the Java solution to the bit fields technique from C (see: Effective Java 2nd Edition: Use EnumSet instead of bit fields).


BitSet to/from int conversion

You might as well just use BitSet and drop the int, but just in case you need these:

static BitSet toBitSet(int i) {
    BitSet bs = new BitSet(Integer.SIZE);
    for (int k = 0; k < Integer.SIZE; k++) {
        if ((i & (1 << k)) != 0) {
            bs.set(k);
        }
    }
    return bs;
}
static int toInt(BitSet bs) {
    int i = 0;
    for (int pos = -1; (pos = bs.nextSetBit(pos+1)) != -1; ) {
        i |= (1 << pos);
    }
    return i;
}

Two different techniques were deliberately used for instructional purposes. For robustness, the BitSet to int conversion should ensure that 32 bits is enough.


EnumSet example

This example is based on the one given in the book:

import java.util.*;
public enum Style {
    BOLD, ITALIC, UNDERLINE, STRIKETHROUGH;

    public static void main(String[] args) {
        Set<Style> s1 = EnumSet.of(BOLD, UNDERLINE);
        System.out.println(s1); // prints "[BOLD, UNDERLINE]"

        s1.addAll(EnumSet.of(ITALIC, UNDERLINE));
        System.out.println(s1.contains(ITALIC)); // prints "true"
    }
}

From the API:

This representation is extremely compact and efficient. The space and time performance of this class should be good enough to allow its use as a high-quality, typesafe alternative to traditional int-based "bit flags."

polygenelubricants
+1 for EnumSet, and book recommendation. That's one of my favorite books, and I barely program in Java anymore.
BlueRaja - Danny Pflughoeft
Wow, great answer; thank you! I'm not sure the enum solution is good for our application since we don't want to hardcode that 20 in "a list of 20 booleans". Actually what we're really doing is remembering a particular subset of the set {1,...,20}.
dreeves
@dreeves: then just use `BitSet`.
polygenelubricants
A: 
// Convert a big-endian bit-vector to an integer. 
int bitvec2int(boolean[] b)
{
    int x = 0;
    for(boolean i : b) x = x << 1 | (i?1:0);
    return x;
}

// Convert an integer x to an n-element big-endian bit-vector. 
boolean[] int2bitvec(int x, int n)
{
    boolean[] b = new boolean[n];
    for(int i = 0; i < n; i++) b[i] = (1 << n-i-1 & x) != 0;
    return b;
}
dreeves
I tested this and confirmed that it works.
dreeves