我们知道bit-map在大数据处理方面有着很大的用途,比如排序,去重等。
JDK 从1.0开始就提供了 java.util.BitSet 来对bit-map的支持。BitSet的set,get操作主要是通过 “位运算” 进行的。
BitSet的核心是一个 long的数组:
- /*
- * BitSets are packed into arrays of "words." Currently a word is
- * a long, which consists of 64 bits, requiring 6 address bits.
- * The choice of word size is determined purely by performance concerns.
- */
- private final static int ADDRESS_BITS_PER_WORD = 6;
- private final static int BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD;
- private final static int BIT_INDEX_MASK = BITS_PER_WORD - 1;
- /* Used to shift left or right for a partial word mask */
- private static final long WORD_MASK = 0xffffffffffffffffL;
- /**
- * The internal field corresponding to the serialField "bits".
- */
- private long[] words;
- /**
- * The number of words in the logical size of this BitSet.
- */
- private transient int wordsInUse = 0;
- /**
- * Whether the size of "words" is user-specified. If so, we assume
- * the user knows what he's doing and try harder to preserve it.
- */
- private transient boolean sizeIsSticky = false;
从bit的角度看,words 应该是一个 二维的bit数据, bit [ ] [64] word, 当然 JDK中没有 bit 这个基本的数据类型。但是JDK提供了丰富的位运算符。每个bit 只有两个值 0 和1(ture 和false)。
bit-map的典型应用场景(伪码表示):
有一个 bit数组 bit [ ] bArray = new bit [ 1024 ]。 要对若干非负整数进行排序,例如:{ 2, 5, 78, 58, 11}。使用bit-map的做法是:
- bArray[2] = 1;
- bArray[5] = 1;
- bArray[78] = 1;
- bArray[58] = 1;
- bArray[11] = 1;
然后顺序遍历bArray就行了。
同样对于BitSet的方法一样,只不过要调用它的set方法,源码如下:
- /**
- * Sets the bit at the specified index to {@code true}.
- *
- * @param bitIndex a bit index
- * @throws IndexOutOfBoundsException if the specified index is negative
- * @since JDK1.0
- */
- public void set(int bitIndex) {
- if (bitIndex < 0)
- throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
- int wordIndex = wordIndex(bitIndex);
- expandTo(wordIndex);
- words[wordIndex] |= (1L << bitIndex); // Restores invariants
- checkInvariants();
- }
如果将 long [ ] words 理解成 bit [ ] [ 64 ] words的话
第一步,先算出一维(wordIndex(int bitIndex) 方法)
- /**
- * Given a bit index, return word index containing it.
- */
- private static int wordIndex(int bitIndex) {
- return bitIndex >> ADDRESS_BITS_PER_WORD;
- }
notice: ADDRESS_BITS_PER_WORD = 6.
第二步,使用位运算对对应的bit进行赋值为1, words[ wordIndex ] |= (1L << bitIndex).
BitSet的get方法和Set方法一样,先确定一维,再通过位运算得到二维中对应的值。
是不是感觉很美妙,通过long数组 再加上 位运算 可以模拟出 bit数组。当然,我们也可以使用int数组或者double行数据来构造 bit数组
相关推荐
本文通过对数据压缩算法的简要介绍,然后以详细的示例演示了利用java.util.zip包实现数据的压缩与解压,并扩展到在网络传输方面如何应用java.util.zip包现数据压缩与解压
1. java.util.concurrent - Java 并发工具包 2. 阻塞队列 BlockingQueue 3. 数组阻塞队列 ArrayBlockingQueue 4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 ...
java.util.ConcurrentModificationException 异常问题详解1
详细介绍了java.util.logging.Logger的用法和结构,对如果扩展Logger起到抛砖引玉的作用!尊重劳动成果,亲下载了要给个评价!
Tomcat内存溢出的解决方法(java.util.concurrent.ExecutionException:java.lang.OutOfMemoryError),内附解决方案!
Exception in thread “main“ java.util.InputMismatchException
java.util.Date与java.sql.Date互转及字符串转换为日期时间格式.docx
java.util.concurrent系列文章(1) java.util.concurrent系列文章(1) java.util.concurrent系列文章(1) java.util.concurrent系列文章(1)
java并发工具包 java.util.concurrent中文版-带书签版
详细介绍java.util.Date和java.sql.Date相互转换的多种方法总结,希望对大家有帮助
这是我在编写struts2中遇到的问题,整理出来,包括截图,希望可以帮到大家
世界范围内的时区列表。由 java.util.TimeZone 类导出
java.util包
java.util包源码,pdf版,方便打印
使用java.util.timer实现的简单定时任务,在实现简单一次性定时任务时,使用java.util.timer非常的简单易用,适合没有接触过quartz的新手急用。
java.util.pdf
java.util包总结,方便大家学习。请多指教。
java.util.concurrent总体概览图。 收取资源分3分。需要的同学可以下载一下。 java.util.concurrent主要包括5个部分executor,colletions,locks,atomic,tools。 该图详细的列举了并发包下面的结构,包含所有接口和...
Java.util包常用接口
Java并发编程工具包java.util.concurrent的UML类结构图 PDF