浅谈Java BitSet使用场景和代码示例

 更新时间:2017年12月08日 16:14:41   作者:温布利往事  
这篇文章主要介绍了浅谈Java BitSet使用场景和代码示例,具有一定借鉴价值,需要的朋友可以参考下。

一、什么是BitSet?

  注:以下内容来自JDK API:

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

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

  每个位 set 都有一个当前大小,也就是该位 set 当前所用空间的位数。注意,这个大小与位 set 的实现有关,所以它可能随实现的不同而更改。位 set 的长度与位 set 的逻辑长度有关,并且是与实现无关而定义的。

一个Bitset类创建一种特殊类型的数组来保存位值。BitSet中数组大小会随需要增加。这和位向量(vectorofbits)比较类似。

这是一个传统的类,但它在Java2中被完全重新设计。

BitSet定义了两个构造方法。

第一个构造方法创建一个默认的对象:

BitSet()

第二个方法允许用户指定初始大小。所有位初始化为0。

BitSet(intsize)

二、Java BitSet实现原理

  在java中,BitSet的实现位于java.util包中:

public class BitSet implements Cloneable, java.io.Serializable 
{
	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;
	private static final ObjectStreamField[] serialPersistentFields =
	   {
	    new ObjectStreamField("bits", long[].class),
}
;
/**
   * The internal field corresponding to the serialField "bits".
   */
private long[] words;
.....
}

可以看到,BitSet的底层实现是使用long数组作为内部存储结构的,所以BitSet的大小为long类型大小(64位)的整数倍。

  它有两个构造函数:

  1、BitSet():创建一个新的位 set,默认大小是64位。

public BitSet() 
{
    initWords(BITS_PER_WORD);
    sizeIsSticky = false;
}

 2、BitSet(int nbits):创建一个位set,它的初始大小足以显式表示索引范围在 0 到 nbits-1 的位。

public BitSet(int nbits)
   {
    // nbits can't be negative; size 0 is OK
    if (nbits < 0)
      throw new NegativeArraySizeException("nbits < 0: " + nbits);
    initWords(nbits);
    sizeIsSticky = true;
  }

  注:

  1、如果指定了bitset的初始化大小,那么会把他规整到一个大于或者等于这个数字的64的整倍数。比如64位,bitset的大小是1个long,而65位时,bitset大小是2个long,即128位。做这么一个规定,主要是为了内存对齐,同时避免考虑到不要处理特殊情况,简化程序。

  2:BitSet的size方法:返回此 BitSet 表示位值时实际使用空间的位数,值是64的整数倍

   length方法:返回此 BitSet 的“逻辑大小”:BitSet 中最高设置位的索引加 1  

三、使用场景

  常见的应用场景是对海量数据进行一些统计工作,比如日志分析、用户数统计等。

  之前在阿里的实习面试就被问到一道题:有1千万个随机数,随机数的范围在1到1亿之间。现在要求写出一种算法,将1到1亿之间没有在随机数中的数求出来?

  代码示例如下: 

public class Alibaba
{
	public static void main(String[] args)
	  {
		Random random=new Random();
		List<Integer> list=new ArrayList<>();
		for (int i=0;i<10000000;i++)
		    {
			int randomResult=random.nextint(100000000);
			list.add(randomResult);
		}
		System.out.println("产生的随机数有");
		for (int i=0;i<list.size();i++)
		    {
			System.out.println(list.get(i));
		}
		BitSet bitSet=new BitSet(100000000);
		for (int i=0;i<10000000;i++)
		    {
			bitSet.set(list.get(i));
		}
		System.out.println("0~1亿不在上述随机数中有"+bitSet.size());
		for (int i = 0; i < 100000000; i++)
		    {
			if(!bitSet.get(i))
			      {
				System.out.println(i);
			}
		}
	}
}

总结

以上就是本文关于浅谈Java BitSet使用场景和代码示例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

您可能感兴趣的文章:

相关文章

  • IDEA下从零开始搭建SpringBoot工程的方法步骤

    IDEA下从零开始搭建SpringBoot工程的方法步骤

    这篇文章主要介绍了IDEA下从零开始搭建SpringBoot工程的方法步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • java中对象为null时的打印输出方式

    java中对象为null时的打印输出方式

    这篇文章主要介绍了java中对象为null时的打印输出方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • spring boot Mybatis 拦截器实现拼接sql和修改的代码详解

    spring boot Mybatis 拦截器实现拼接sql和修改的代码详解

    这篇文章主要介绍了spring boot Mybatis 拦截器实现拼接sql和修改,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • resttemplate设置params的方法

    resttemplate设置params的方法

    RestTemplate设置请求参数的方式根据请求类型(GET/POST)和参数形式(路径参数、查询参数、JSON请求体)有所不同,下面通过本文给大家介绍resttemplate设置params的方法,感兴趣的朋友一起看看吧
    2025-04-04
  • Spring中@Scheduled注解的参数详解

    Spring中@Scheduled注解的参数详解

    这篇文章主要介绍了Spring中@Scheduled注解的参数详解,@Scheduled注解的使用这里不详细说明,@Scheduled注解有几个参数需要说明一下,直接对8个参数进行讲解,需要的朋友可以参考下
    2023-11-11
  • 详解Java中Math.round()的取整规则

    详解Java中Math.round()的取整规则

    这篇文章主要介绍了详解Java中Math.round()的取整规则,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • springboot2.2 集成 activity6实现请假流程(示例详解)

    springboot2.2 集成 activity6实现请假流程(示例详解)

    这篇文章主要介绍了springboot2.2 集成 activity6实现请假完整流程示例详解,本文通过示例代码图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • SpringBoot自定义starter启动器的实现思路

    SpringBoot自定义starter启动器的实现思路

    这篇文章主要介绍了SpringBoot如何自定义starter启动器,通过starter的自定义过程,能够加深大家对SpringBoot自动配置原理的理解,需要的朋友可以参考下
    2022-10-10
  • Servlet从入门到精通(超级详细!)

    Servlet从入门到精通(超级详细!)

    在JavaWeb项目中,处理请求和发送响应的过程是由一种叫做Servlet 的程序来完成的,并且 Servlet 是为了解决实现动态页面而衍生的东西,下面这篇文章主要给大家介绍了关于Servlet从入门到精通的相关资料,需要的朋友可以参考下
    2022-03-03
  • springboot+redis自定义注解实现发布订阅的实现代码

    springboot+redis自定义注解实现发布订阅的实现代码

    在Redis中客户端可以通过订阅特定的频道来接收发送至该频道的消息,本文主要介绍了springboot+redis自定义注解实现发布订阅,具有一定的参考价值,感兴趣的可以了解一下
    2023-08-08

最新评论