跳到主要内容

Java 位图

位图(BitSet)是一种特殊的类,它可以用来存储位值(0 或 1),可以按需调整大小,并且可以对位数据进行操作,如设置,清除,反转等。它比其他存储位值的数据结构更快,可以更有效地管理内存。

相关 API:

  • void set(int index):将指定索引处的位设置为true
  • void clear(int index):将指定索引处的位设置为false
  • boolean get(int index):返回指定索引处的位的值
  • int size():返回 BitSet 中位的总数
  • void flip(int index):反转指定索引处的位的值
  • void and(BitSet set):将此BitSet与指定的BitSet的按位与操作结果存储到当前BitSet中
  • void or(BitSet set):将此BitSet与指定的BitSet的按位或操作结果存储到当前BitSet中
  • void xor(BitSet set):将此BitSet与指定的BitSet的按位异或操作结果存储到当前BitSet中

示例:

public static void main(String[] args) {
// 创建了两个位图对象(bits1和bits2),用于存储16位数据
BitSet bs1 = new BitSet(16);
BitSet bs2 = new BitSet(16);

System.out.println("bs1 is " + bs1); // bs1 is {}
System.out.println("bs2 is " + bs2); // bs2 is {}

// 放一些数到bitset里面
for (int i = 0; i < 16; i++) {
if ((i % 2) == 0) {
bs1.set(i);
}
if ((i % 5) != 0) {
bs2.set(i);
}
}
System.out.println("bs1 is " + bs1); // bs1 is {0, 2, 4, 6, 8, 10, 12, 14}
System.out.println("bs2 is " + bs2); // bs2 is {1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14}

// AND bits 位与运算
bs2.and(bs1);
System.out.println("bits2 AND bits1:" + bs2); // bits2 AND bits1:{2, 4, 6, 8, 12, 14}

// OR bits 位或运算
bs2.or(bs1);
System.out.println("bits2 OR bits1:" + bs2); // bits2 OR bits1:{0, 2, 4, 6, 8, 10, 12, 14}

// XOR bits 位抑或运算
bs2.xor(bs1);
System.out.println("bits2 XOR bits1:" + bs2); // bits2 XOR bits1:{}
}

说明:

  • and:将两个位图按位与操作,即将两个位图中的每一位相与,结果为1的位才保留
  • or:将两个位图按位或操作,即将两个位图中的每一位进行相或,结果为1的位才保留
  • xor:将两个位图按位异或操作,即将两个位图中的每一位进行相异或,结果为1的位才保留

计算机是一种基于二进制运算的机器。它使用一组二进制数字和特定的运算符号(如加号、减号、与、或和异或)来进行计算和控制。而与,或,异或是计算机底层做计算时常用的几种运算符。

与,或,异或运算是什么?

  • 与运算:两个操作数的比较,只要有一个操作数为 0,结果就为 0,只有两个操作数都为 1,结果才为 1
  • 或运算:两个操作数的比较,只要有一个操作数为 1,结果就为 1,只有两个操作数都为 0,结果才为 0
  • 异或运算:两个操作数的比较,当两个操作数不相同时,结果为 1,当两个操作数相同时,结果为 0

在进行这类运算之前,首先需要将数字转换为二进制的格式进行运算,然后在进行相关操作

示例:

  • 10 与 5 的运算结果为 0:10 & 5 = 0
  • 10 或 5 的运算结果为 15:10 | 5 = 15
  • 10 异或 5 的运算结果为 15:10 ^ 5 = 15

以 10 & 5 = 0 为例:

位图有什么优点?

  • 操作简单,可以实现位运算,如 &、|、^ 等
  • 存储空间小,一般比不使用 bitset 时的存储空间要小很多
  • 时间复杂度低,多数操作的时间复杂度是 O(1)
  • 可以检索指定位是否为 1,可以检索指定位是否为 0
  • 节省空间,比如存储一个 0-1000000 之间的数字,如果使用数组存储,需要 8M 的空间,而使用 bitset 只需要 13K 的空间

使用场景?