RoaringBitmap的使用方法

这篇文章主要介绍“RoaringBitmap的使用方法”,在日常操作中,相信很多人在RoaringBitmap的使用方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”RoaringBitmap的使用方法”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1、简单Demo

参考: RoaringBitmap

public class Demo {

    @Test
    public void test1(){
        // 向r1中添加1、2、3、1000四个数字
        RoaringBitmap r1 = RoaringBitmap.bitmapOf(1, 2, 3, 1000);
        // 返回第3个数字是1000
        System.out.println(r1.select(3));

        r1.add(5);

        // 返回10000的索引,是4
        System.out.println(r1.rank(1000));
        System.out.println(r1.rank(3));
        System.out.println(r1.rank(2));
        System.out.println(r1.rank(1));

        // 是否包含1000和7,true和false
        System.out.println(r1.contains(1000));
        System.out.println(r1.contains(7));

        RoaringBitmap r2 = new RoaringBitmap();
        // 向r2添加10000-12000共2000个数字
        r2.add(10000L, 12000L);

        // 将两个r1,r2进行合并,数值进行合并,合并产生新的RoaringBitmap
        RoaringBitmap r3 = RoaringBitmap.or(r1, r2);

        // r1和r2进行位运算,并将结果赋值给r1
        r1.or(r2);

        // 判断r1与r3是否相等,true
        System.out.println(r1.equals(r3));

        // 查看r1中存储了多少个值,2004
        System.out.println(r1.getLongCardinality());

        // 两种遍历方式
        for(int i : r1){
            System.out.println(i);
        }

        r1.forEach((Consumer<? super Integer>) i -> System.out.println(i.intValue()));
    }

    @Test
    public void test2(){
        RoaringBitmap roaringBitmap = new RoaringBitmap();
        roaringBitmap.add(1L, 10L);

        // 遍历输出
        roaringBitmap.forEach((IntConsumer)i -> System.out.println(i));

        // 遍历放入List中
        List<Integer> numbers = new ArrayList<>();
        roaringBitmap.forEach((IntConsumer) numbers::add);
        System.out.println(numbers);

        roaringBitmap.runOptimize();

        int size = roaringBitmap.serializedSizeInBytes();
        ByteBuffer buffer = ByteBuffer.allocate(size);
        roaringBitmap.serialize(buffer);
        // 将RoaringBitmap的数据转成字节数组,这样就可以直接存入数据库了,数据库字段类型BLOB
        byte[] bitmapData = buffer.array();
    }
}
// List变成RoaringBitmap
private RoaringBitmap buildBitmap(List<String> idList) {
    RoaringBitmap roaringBitmap = new RoaringBitmap();
    idList.forEach(id -> roaringBitmap.add(Integer.valueOf(id.trim())));
    roaringBitmap.runOptimize();
    return roaringBitmap;
}
// a + b - c
private RoaringBitmap mergeBitmap(List<RoaringBitmap> a, List<RoaringBitmap> b,
                                                         List<RoaringBitmap> c) {  
    // a + b
    List<RoaringBitmap> blacklistBitMaps = Lists.newLinkedList();
    blacklistBitMaps.addAll(a);
    blacklistBitMaps.addAll(b);
    RoaringBitmap blacklistBitMap = aggregationToBitMap(blacklistBitMaps);
        
    // c 
    RoaringBitmap whitelistBitMap = aggregationToBitMap(c);
        
    // a + b - c
    blacklistBitMap.andNot(whitelistBitMap);
        
    return blacklistBitMap;
}

private RoaringBitmap aggregationToBitMap(List<RoaringBitmap> list) {
    if (CollectionUtils.isEmpty(list)) {
        return new RoaringBitmap();
    }
    if (list.size() == 1) {
        return list.get(0);
    }
    return FastAggregation.or(list.listIterator());
}

2、和数据库Blob字段结合使用

create table hobby
(
    id int auto_increment primary key,
    name varchar(255) not null,
    hobbies blob null
);
// 忽略get、set方法
public class HobbyDO {

    private Integer id;

    private String name;

    private RoaringBitmap bitmap;
}
public interface HobbyDOMapper {
    int insert(HobbyDO record);

    HobbyDO selectByPrimaryKey(Integer id);
	
    Integer updateBitmap(@Param("id") Integer id, @Param("bitmap") byte[] bitmap);
}
public class HobbyBitmapBlobHandler extends BaseTypeHandler<RoaringBitmap> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, RoaringBitmap parameter, JdbcType jdbcType)
            throws SQLException {
        byte[] content = serializeRoaringBitmap(parameter);

        if (content == null) {
            return;
        }

        ByteArrayInputStream bis = new ByteArrayInputStream(content);
        ps.setBinaryStream(i, bis, content.length);
    }

    @Override
    public RoaringBitmap getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return deSerializeRoaringBitmap(rs.getBlob(columnName));
    }

    @Override
    public RoaringBitmap getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return deSerializeRoaringBitmap(rs.getBlob(columnIndex));
    }

    @Override
    public RoaringBitmap getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return deSerializeRoaringBitmap(cs.getBlob(columnIndex));
    }

    private byte[] serializeRoaringBitmap(RoaringBitmap roaringBitmap) {
        if (roaringBitmap == null) {
            return null;
        }

        int size = roaringBitmap.serializedSizeInBytes();

        ByteBuffer buffer = ByteBuffer.allocate(size);

        roaringBitmap.serialize(buffer);

        return buffer.array();
    }

    private RoaringBitmap deSerializeRoaringBitmap(Blob blob) {
        if (blob == null) {
            return null;
        }

        byte[] content;
        try {
            content = blob.getBytes(1, (int) blob.length());
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }

        ByteBuffer buffer = ByteBuffer.wrap(content);
        return new RoaringBitmap(new ImmutableRoaringBitmap(buffer));
    }
}

RoaringBitmap的使用方法

@Test
public void insert() {
    HobbyDO hobby = new HobbyDO();
    hobby.setName("lwh");

    RoaringBitmap bitmap = new RoaringBitmap();
    bitmap.add(111);
    bitmap.add(222);
    bitmap.add(333);

    hobby.setBitmap(bitmap);

    hobbyDOMapper.insert(hobby);
}

@Test
public void update(){
    RoaringBitmap bitmap = new RoaringBitmap();
    bitmap.add(133);
    bitmap.add(222);
    bitmap.add(333);

    int size = bitmap.serializedSizeInBytes();
    ByteBuffer buffer = ByteBuffer.allocate(size);
    bitmap.serialize(buffer);

    byte[] bitmapData = buffer.array();
    hobbyDOMapper.updateBitmap(1, bitmapData);
}

@Test
public void select(){
    HobbyDO hobbyDO = hobbyDOMapper.selectByPrimaryKey(1);

    hobbyDO.getBitmap().forEach((IntConsumer) System.out::println);
}

到此,关于“RoaringBitmap的使用方法”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!