一、序言
在实际开发中常常遇到如下需求:判断当前元素是否存在于已知的集合中,将已知集合中的元素维护一个HashSet
,使用时只需耗时O(1)
的时间复杂度便可判断出结果,Java内部或者Redis均提供相应的数据结构。使用此种方式除了占用内存空间外,几乎没有其它缺点。
当数据量达到亿级别时,内存空间的占用显著表现出来,BitMap
便是解决此类问题的一种途径。
二、BitMap结构
1、内存消耗分析
Redis BitMap能够存储的数据范围为[0,2^32-1]
,超过Integer.MAX_VALUE
上界值。
为了简化讨论,假设讨论的集合元素的范围为[0,Integer.MAX_VALUE]
,可以是其中的任何一个数。
使用HashSet
数据结构占用内存空间仅与集合中的元素数量(N)相关。当集合中元素数量为N时,所需的内存空间大概为N*4/1024/1024
MB,1亿
条数据约占内存空间381MB
。
基于Redis的BitMap所占用的空间大小不与集合中元素数量相关,与集合中元素的最大值直接相关,因此BitMap所占用的内存空间范围为[N / 8 / 1024 / 1024,Integer.MAX_VALUE / 8 / 1024 / 1024]
。
// 测试1亿、5亿、10亿、Integer.MAX_VALUE
List<Integer> items = Arrays.asList(100000000, 500000000, 100