1:Bitset介绍

BitSet 是用于存储二进制位和对二进制进行操作的 自动去重Java 数据结构,

此类实现了一个按需增长的位向量。位 set 的每个组件都有一个 boolean 值。用非负的整数将 BitSet 的位编入索引。可以对每个编入索引的位进行测试、设置或者清除。通过逻辑与、逻辑或和逻辑异或操作,可以使用一个 BitSet 修改另一个 BitSet 的内容。

默认情况下,set 中所有位的初始值都是 false

2:优化空间

在程序runtime时,我们经常需要使用数组来记住程序的运行状态,并且根据这些状态及时 对数据做出更新,一般有以下处理办法

  • 使用 Int [] state=new int[22]; 保存状态
  • 使用 boolean [] state = new boolean[22] 保存状态

分析可知,1byte=8bit  int占用4个字节,如果考虑使用bit直接存储状态 ,将会大大节约时间, 不过在改变你的编程习惯之前,你应该清楚 我们如何保存状态,以及对于状态的操作

3:Bitset常用api

构建

BitSet()
创建一个新的位 set。 默认64
BitSet(int nbits)
创建一个位 set,它的初始大小足以显式表示索引范围在 到 nbits- 的位。 一般要求给出大小 当给出的值小于实际需要的值,会自动扩容

操作

更新:  
void set(int bitIndex)
将指定索引处的位设置为 true。
void set(int bitIndex, boolean value)
将指定索引处的位设置为指定的值。
void set(int fromIndex, int toIndex)
将指定的 fromIndex(包括)到指定的 toIndex(不包括)范围内的位设置为 true。
void set(int fromIndex, int toIndex, boolean value)
将指定的 fromIndex(包括)到指定的 toIndex(不包括)范围内的位设置为指定的值。
获取:
boolean get(int bitIndex)
          返回指定索引处的位值。
 BitSet get(int fromIndex,
int toIndex)

          返回一个新的 BitSet,它由此 BitSet 中从
fromIndex(包括)到 toIndex(不包括)范围内的位组成。
翻转:
boolean get(int bitIndex)
          返回指定索引处的位值。
 BitSet get(int fromIndex,
int toIndex)

          返回一个新的 BitSet,它由此 BitSet 中从
fromIndex(包括)到 toIndex(不包括)范围内的位组成。
删除 
 void clear()
          将此 BitSet 中的所有位设置为 false
 void clear(int bitIndex)

          将索引指定处的位设置为 false
 void clear(int fromIndex,
int toIndex)

          将指定的 fromIndex(包括)到指定的
toIndex(不包括)范围内的位设置为 false
长度:
 int cardinality()
          返回此 BitSet 中设置为 true 的位数。

int length()
          返回此 BitSet 的“逻辑大小”:BitSet 中最高设置位的索引加 1。
 
 int size()
          返回此 BitSet 表示位值时实际使用空间的位数。
重要: 遍历相关:

 int nextClearBit(int fromIndex)
          返回第一个设置为 false 的位的索引,这发生在指定的起始索引或之后的索引上。
 int nextSetBit(int fromIndex)

          返回第一个设置为 true 的位的索引,这发生在指定的起始索引或之后的索引上。
 

4.BitSet 应用举例

统计随机个数

    private final static int LEN_NUM = 10;
public static void main(String[] args) {
BitSet set = new BitSet(); ArrayList<Integer> list = new ArrayList<>(); Random random = new Random();
for (int i = 0; i < LEN_NUM; i++) {
list.add(random.nextInt(100));
}
for (int i = 0; i < list.size(); i++) {
set.set(list.get(i));
}
for (int i = 0; i < 10; i++) {
if(!set.get(i)) { //输出不在10范围以内的个数
System.out.print(i+" ");
}
}
System.out.println();
System.out.println("有true的多少个"+set.cardinality());
}

输出素数:

// 原始
public static void main(String[] s) {
int n = 1000000;
long start = System.currentTimeMillis();
int[] hash = new int[n + 1];
for (int i = 2; i < n; i++) {
if (hash[i] == 0) {
for (int j = 2 * i; j < n; j += i) {
hash[j] = 1;
}
}
}
long end = System.currentTimeMillis();
System.out.println((end - start) + " ms");
}
// 改进后的 public static void main(String[] args) {
long start = System.currentTimeMillis();
BitSet bitSet = new BitSet(10000000);
for (int i = 2; i < 1000000; i++) {
if(!bitSet.get(i)) {
for (int j = i*2; j <1000000 ; j+=i) {
bitSet.set(j,true);
}
}
}
for (int i = 0; i < 1000000; i++) {
if(!bitSet.get(i)) {
System.out.println(i+" ");
}
}
long end = System.currentTimeMillis();
System.out.println((end - start) + " ms");
}

对不同数据进行排序

场景是无序数组: 因为bitset 自动去重

private static  Random random=new Random();

        private static Set<Integer> set=new HashSet<>(); //

        public static void init() {
for (int i = 0; i < 1000; i++) {
set.add(random.nextInt(1000));
}
} public static void main(String[] args) {
init();
BitSet bitSet = new BitSet(); Integer [] x=new Integer[set.size()];
Integer[] array = set.toArray(x);
for (int i = 0; i < array.length; i++) {
bitSet.set(array[i]);
}
int bitLen=bitSet.cardinality();
int[] orderedArray = new int[bitLen]; int k=0;
for (int i = bitSet.nextSetBit(0); i >= 0; i = bitSet.nextSetBit(i + 1)) {
orderedArray[k++] = i;
} for (int i = 0; i < bitLen; i++) {
System.out.println(orderedArray[i]);
}
}

并交补运算

 public static void main(String[] args) {
BitSet bitSet = new BitSet(100);
bitSet.set(1);
bitSet.set(2);
bitSet.set(3); BitSet bitSet2 = new BitSet(100);
bitSet2.set(2);
bitSet2.set(3);
bitSet2.set(5); System.out.println("刚开始的bitSet:"+bitSet);
System.out.println("刚开始的bitSet2:"+bitSet2);
System.out.println("------------------------------");
//求并集
bitSet.or(bitSet2);
System.out.println("求完并集之后的bitSet:"+bitSet);
System.out.println("求完并集之后的bitSet2:"+bitSet2);
System.out.println("------------------------------");
//使bitSet回到刚开始的状态
bitSet.clear(5); //求交集
bitSet.and(bitSet2);
System.out.println("求完交集之后的bitSet:"+bitSet);
System.out.println("求完交集之后的bitSet2:"+bitSet2);
System.out.println("------------------------------");
//使bitSet回到刚开始的状态
bitSet.set(1);
//此方法返回在bitSet中不在bitSet2中的值,求的是bitSet相对于bitSet2的补集
bitSet.andNot(bitSet2);
System.out.println("求完补集之后的bitSet:"+bitSet);
System.out.println("求完补集之后的bitSet2:"+bitSet2);
}

Bitset操作 是比较耗CPU的,但是速度快

Bitset改进你的程序质量的更多相关文章

  1. 一道面试题与Java位操作 和 BitSet 库的使用

    前一段时间在网上看到这样一道面试题: 有个老的手机短信程序,由于当时的手机CPU,内存都很烂.所以这个短信程序只能记住256条短信,多了就删了. 每个短信有个唯一的ID,在0到255之间.当然用户可能 ...

  2. 牛客练习赛22 简单瞎搞题(bitset优化dp)

    一共有 n个数,第 i 个数是 xi  xi 可以取 [li , ri] 中任意的一个值. 设 ,求 S 种类数. 输入描述: 第一行一个数 n. 然后 n 行,每行两个数表示 li,ri.   输出 ...

  3. Java 8 的新特性和改进总览

    这篇文章是对Java 8中即将到来的改进做一个面向开发者的综合性的总结,JDK的这一特性将会在2013年9月份发布. 在写这篇文章的时候,Java 8的开发工作仍然在紧张有序的进行中,语言特新和API ...

  4. 【Bitset】重识

    ---------------------------------------------------------------------------- 一题题目: 一题题解: 这个题目哪来入门再好不 ...

  5. POJ 3155 Hard Life(最大密度子图+改进算法)

    Hard Life Time Limit: 8000MS   Memory Limit: 65536K Total Submissions: 9012   Accepted: 2614 Case Ti ...

  6. 120项改进:开源超级爬虫Hawk 2.0 重磅发布!

    沙漠君在历时半年,修改无数bug,更新一票新功能后,在今天隆重推出最新改进的超级爬虫Hawk 2.0! 啥?你不知道Hawk干吗用的? 这是采集数据的挖掘机,网络猎杀的重狙!半年多以前,沙漠君写了一篇 ...

  7. 基于改进人工蜂群算法的K均值聚类算法(附MATLAB版源代码)

    其实一直以来也没有准备在园子里发这样的文章,相对来说,算法改进放在园子里还是会稍稍显得格格不入.但是最近邮箱收到的几封邮件让我觉得有必要通过我的博客把过去做过的东西分享出去更给更多需要的人.从论文刊登 ...

  8. 挑子学习笔记:两步聚类算法(TwoStep Cluster Algorithm)——改进的BIRCH算法

    转载请标明出处:http://www.cnblogs.com/tiaozistudy/p/twostep_cluster_algorithm.html 两步聚类算法是在SPSS Modeler中使用的 ...

  9. ITTC数据挖掘平台介绍(四) 框架改进和新功能

    本数据挖掘框架在这几个月的时间内,有了进一步的功能增强 一. 超大网络的画布显示虚拟化     如前几节所述,框架采用了三级层次实现,分别是数据,抽象Node和绘图的DataPoint,结构如下:   ...

随机推荐

  1. 如何在Centos服务器上搭建起Oracle10、VNC、以及FTP

    一.重装和分区 1.配置所需磁盘阵列(Raid): 2.正确分区: 3.Centos安装:过于简单,请自行bd. 二.连网 系统安装完成之后,我们需为其分配IP和DNS: "编辑连接&quo ...

  2. FreeSql (三十一)分区分表

    分区 分区就是把一个数据表的文件和索引分散存储在不同的物理文件中.把一张表的数据分成N多个区块,这些区块可以在同一个磁盘上,也可以在不同的磁盘上,数据库不同实现方式有所不同. 与分表不同,一张大表进行 ...

  3. json-lib包引入失败的解决方法

    要想使用json-lib的依赖必须加入<classifier>jdk15</classifier> 这一行,否则就导入依赖时就会失败报错,下载不下来jar包,因为json-li ...

  4. linux下tomcat无法远程访问(开放8080端口)

    我们在linux下配置了tomcat后发现,无法访问除了linux(如果是虚拟机的话,宿主机子根本无法访问tomcat),解决下吧 原因是我们的tomcat访问需要8080端口,但是从外部访问,我们的 ...

  5. Yum未完成事务问题

    1.安装 yum-complete-transaction [root@linux-node1 ~]# yum -y install yum-utils 2.清除yum缓存 [root@linux-n ...

  6. C++解决最基本的迷宫问题

    问题描述:给定一个最基本的迷宫图,用一个数组表示,值0表示有路,1表示有障碍物,找一条,从矩阵的左上角,到右下角的最短路.求最短路,大家最先想到的可能是用BFS求,本文也是BFS求最短路的. 源代码如 ...

  7. .netCore部署在IIS上遇到的问题(500.19,500.21错误)

    1.确保IIS功能都安装上了. 2.确保.netcore 的最新sdk已安装. 3.应用程序池改成无托管代码 4.500.19错误 错误原因,没有安装 DotNetCore.2.0.5-Windows ...

  8. 2019年9月3日安卓凯立德全分辨率(路况)夏季版C3551-C7M24-3K21J25懒人包

    拷贝懒人包NaviOne文件夹到机器根目录或内存卡根目录下:安装其中的apk程序 2019凯立德C3551-C7M24-3K21J25新组合懒人包 [分辨率]:自适应 [适用系统]:Android2. ...

  9. spring框架对于实体类复杂属性注入xml文件的配置

    spring框架是javaWeb项目中至关重要的一个框架,大多web 项目在工作层次上分为持久层.服务层.控制层.持久层(dao.mapper)用于连接数据库,完成项目与数据库中数据的传递:服务层(s ...

  10. 痞子衡嵌入式:飞思卡尔i.MX RTyyyy系列MCU硬件那些事(1)- 官方EVK简介

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RTyyyy系列MCU的配套EVK板. 半导体设计厂商发布任何一块MCU芯片新品,一般都会同步推出基于这款MCU的配套 ...