0

取消以下功能的最佳方法是什么?

// 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]
}

或者有没有比传递布尔数组更好的方法来做这种事情?

这出现在一个 Android 应用程序中,我们需要一个包含 20 个布尔值的数组来持久化,最简单的方法是将整数或字符串写入键值存储。

我将发布我们(蜜蜂和我)写以上内容的方式作为答案。谢谢!

4

2 回答 2

9

改为使用java.util.BitSet。它会比处理快得多boolean[]

此外,您真的应该问自己这 20 个是否boolean真的应该是enum,在这种情况下,您可以使用EnumSetC 中位域技术的 Java 解决方案(请参阅:Effective Java 2nd Edition: Use EnumSetinstead of bit fields)。


BitSet到/从int转换

您也可以使用BitSet并删除int,但以防万一您需要这些:

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;
}

两种不同的技术被故意用于教学目的。为了鲁棒性,BitSettoint转换应确保 32 位就足够了。


EnumSet例子

此示例基于书中给出的示例:

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"
    }
}

API

这种表示非常紧凑和高效。int这个类的空间和时间性能应该足够好,以允许它用作传统的基于“位标志”的高质量、类型安全的替代品。

于 2010-05-08T16:38:23.463 回答
1
// 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;
}
于 2010-05-08T16:38:39.103 回答