RoaringBitmap等工具类的使用,以及搜索算法


java自带的bitset只提供了基本的功能,不算很强大。所以实际开发中要借助其他类库,例如RoaringBitmap。

RoaringBitmap在方法的丰富性上,以及性能上都有提高。

jdk自带bitSet

bitSet示例

bitSet比较主流,示例很多:

@Slf4j
public class BitSetDemo {
	public static void main(String[] args) {

			// 1 小明
			// 2 小刚
			// 3 建军
			// 4 小红
			// 1000 小花
			// 2000 小丽

			BitSet appleBitSet = new BitSet(); // appleBitSet
			appleBitSet.set(4);
			appleBitSet.set(1000);


			BitSet huaweiBitSet = new BitSet(); // huaweiBitSet
			huaweiBitSet.set(1);
			huaweiBitSet.set(2);

			BitSet vivoBitSet = new BitSet(); // vivoBitSet
			vivoBitSet.set(2000);

			BitSet maleBitSet = new BitSet(); // maleBitSet
			maleBitSet.set(1);
			maleBitSet.set(2);
			maleBitSet.set(3);
			BitSet femaleBitSet = new BitSet(); // femaleBitSet
			femaleBitSet.set(4);
			femaleBitSet.set(1000);

			BitSet appleMaleSet = (BitSet)appleBitSet.clone();
			// 求 苹果的女性
			appleMaleSet.and(femaleBitSet);
			log.info("用苹果的女性={}",appleMaleSet);

			// 小明是否用苹果
			boolean b = appleBitSet.get(1);
			log.info("小明是否用苹果={}",b);

			// 清除appleBitSet的第一位 (应该是清楚第4位才可以)
			appleBitSet.clear(4);
			appleBitSet.flip(4); // 反转
			log.info("清除appleBitSet的第一位,appleBitSet={}",appleBitSet);

			// false和无值的区别

	}
}

bitset常用方法

1、set设置值。
2、flip() 反转,true变false,false变true。
3、clear() 清除,相当于设置为false。
4、and() 且操作。(因为会改变原集合,所以要先clone,用clone的进行and操作)
5、or() 或操作。

注:bitmap的or不能直接实现,但是bitset也支持了,很方便。

bitset打印出来是怎样的,实际类似于json,例如:{1,2,3,100,2000}。所以无论放到数据库还是文件,存取都比较方便的。

存到数据库还是文件里

当数据量很大时,bitmap会很大,存到哪里成为了一个问题。
存文件吧,主要是io流的开销也挺大,尤其是需要频繁读写的时候。
存数据库吧,因为数据太大,效率也不高。
频繁修改的数据,最好借助内存。

RoaringBitmap

maven引入

第2个是roaringbitmap,但是一块贴上了啊。

<dependency>
    <groupId>uk.gov.gchq.gaffer</groupId>
    <artifactId>bitmap-library</artifactId>
    <version>1.21.1</version>
</dependency>
<dependency>
    <groupId>org.roaringbitmap</groupId>
    <artifactId>RoaringBitmap</artifactId>
    <version>0.9.22</version>
</dependency>

其他可用的RoaringBitmap版本,如果0.9.20、0.8.12等,都可以参考下。

RoaringBitmap 基本用法,包括文件流

public static void main(String[] args) throws Exception{
    String filePath="d://bit.txt";
    RoaringBitmap roaringBitmap = new RoaringBitmap ();
    roaringBitmap.add(1);
    roaringBitmap.add(20000);
    serialize(roaringBitmap,filePath);

    RoaringBitmap deserialize = deserialize(filePath);
    // RoaringBitmap 最大的特点就是 带有压缩,例如 添加一个很大的数,基数不会跳跃
    logger.info("getCardinality:{}",deserialize.getCardinality());
}

// 序列化 保存
public static void serialize(RoaringBitmap  roaringBitmap,String filePath) throws IOException {
    roaringBitmap.serialize(new DataOutputStream(new FileOutputStream(filePath)));
}

// 反序列化  读取
public static RoaringBitmap deserialize(String filePath) throws IOException {
    RoaringBitmap  roaringBitmap = new RoaringBitmap ();
    roaringBitmap.deserialize(new DataInputStream(new FileInputStream(filePath)));
    return roaringBitmap;
}

这段代码实测少类

这个代码不行啊,0.9.20和0.9.22版本都拿到了。是不是MutableRoaringBitmap太高级了。

import org.roaringbitmap.RoaringBitmap;
import org.roaringbitmap.buffer.ImmutableRoaringBitmap;
import org.roaringbitmap.buffer.MutableRoaringBitmap;

public class EWAHCompressedBitmapExample {
    public static void main(String[] args) {
        // 创建一个可变的RoaringBitmap
        MutableRoaringBitmap mutableBitmap = new MutableRoaringBitmap();

        // 添加值
        mutableBitmap.add(1);
        mutableBitmap.add(2);
        mutableBitmap.add(3);

        // 转换为不可变的RoaringBitmap
        ImmutableRoaringBitmap immutableBitmap = mutableBitmap.toImmutableRoaringBitmap();

        // 检查值是否存在
        boolean contains1 = immutableBitmap.contains(1); // true
        boolean contains4 = immutableBitmap.contains(4); // false

        // 输出基本信息
        System.out.println("Cardinality: " + immutableBitmap.getCardinality()); // 输出3
        System.out.println("Contains 1: " + contains1);
        System.out.println("Contains 4: " + contains4);
    }
}

其他工具类

还有很多,如:
ArrayContainer
RunContainer

搜索算法数据库设计

数据库设计可以为

t_bitset
category 大类(如性别,设备类型等)
type 类型(如男、女,android、ios等)
fileName 文件名
filePath 文件路径

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值