bitmap java实现简易版
不多说 直接上代码 里面有注释, 功能写的比较简单 只实现了简单的扩容,并且很臃肿比较浪费空间,并且不能存负数 只能存储>=0的 int类型数字,其他类型也可以自己试着实现,主要是了解bitmap
但是用于学习是足够了 首先需要了解一下bitmap实现的原理 建议看这篇博客 本人也是学习了这篇博客后增加了一个动态扩容的方法而已
参考博客链接
BitMap的原理和实现
package com.aop.java_aop.bean;
import com.sun.istack.internal.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author yangwh
* 简易版动态扩容型bitmap
* @createTime 2020/9/7 0007 15:44
*/
public class DBitMap {
//默认给4个长度
private long[] maps;
private int length;
private List<Integer> reallyData;
public DBitMap() {
this.length = 4;
this.maps = new long[length];
this.reallyData =new ArrayList<>();
}
public DBitMap(int length) {
this.length = length;
this.maps = new long[length];
this.reallyData =new ArrayList<>();
}
public DBitMap(@NotNull List<Integer> data) {
int max = data.stream().mapToInt(a -> a).max().getAsInt();
this.length = (max & 63) == 0 ? max >> 6 : (max >> 6) + 1;
maps = new long[length];
this.reallyData=data;
for (int i = 0; i <data.size() ; i++) {
add(data.get(i));
}
}
/**
* 功能说明:将该数字标识到数组对应的位上设置为1
* @createTime 2020/09/08 15:08
* @author yangwh
* @param one
* @return void
*/
public void add(int one){
//如果该数字超过存储长度 则进行扩容
int newLength =(one & 63) == 0 ? one >> 6 : (one >> 6) + 1;
if (newLength >length){
length = newLength;
maps= Arrays.copyOf(maps,newLength);
}
//已经存在直接return
if (contains(one)){
System.out.println("存在=="+one);
return;
}
maps[getIndex(one)] |= 1L << getPosition(one);
System.out.println(one+"==set数据到数组的第"+(getIndex(one)+1)+"个数字的第"+(getPosition(one)+1)+"位");
reallyData.add(one);
}
/**
* 功能说明:判断数字是否存在与bitmap中
* 将1左移position后,那个位置自然就是1,然后和以前的数据做&,判断是否为0即可
* @createTime 2020/09/08 15:40
* @author yangwh
* @param one
* @return boolean
*/
public boolean contains(int one){
return (maps[getIndex(one)] & (1L<< getPosition(one))) != 0;
}
/**
* 功能说明:获取该数在数组中的下标 0-...
* @createTime 2020/09/08 15:05
* @author yangwh
* @param one
* @return int
*/
private int getIndex (int one){
return one >> 6;
}
/**
* 功能说明:计算该数字在第几位
* @createTime 2020/09/08 15:06
* @author yangwh
* @param one
* @return int
*/
private int getPosition(int one){
return one&63;
}
/**
* 功能说明:输出倒序排列的已存在的数字list
* 建议使用这种方式输出.
* @createTime 2020/09/08 15:23
* @author yangwh
* @param
* @return java.util.List<java.lang.Integer>
*/
public List<Integer> descOne(){
List<Integer> result=new ArrayList<>(reallyData.size()+1);
for (int i = length-1; i >= 0 ; i--) {
byte[] bytes =getBytes(maps[i]);
for (int j = bytes.length-1; j >=0 ; j--) {
int reallyInt = bytes[j] == 0 ? -1 : (i*64+j);
if (reallyInt >=0){
result.add(reallyInt);
}
}
}
return result;
}
public List<Integer> descTwo(){
List<Integer> result=reallyData.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
return result;
}
public List<Integer> ascTwo(){
List<Integer> result=reallyData.stream().sorted().collect(Collectors.toList());
return result;
}
public List<Integer> ascOne(){
List<Integer> result=new ArrayList<>(reallyData.size()+1);
for (int i = 0; i <length ; i++) {
byte[] bytes =getBytes(maps[i]);
for (int j = 0; j <bytes.length ; j++) {
int reallyInt = bytes[j] == 0 ? -1 : (i*64+j);
if (reallyInt >=0){
result.add(reallyInt);
}
}
}
return result;
}
/**
* 功能说明:将数字的二进制码返回为 byte数组 [0,1,1,0,1,1,1,1]...
* @createTime 2020/09/08 15:31
* @author yangwh
* @param one
* @return byte[]
*/
public byte[] getBytes(long one){
byte[] re =new byte[64];
for (int i = 0; i <64 ; i++) {
re[i] = (byte) (one & 1) ;
one =(one >>1);
}
return re;
}
public static void main(String[] args) {
DBitMap bitmap =new DBitMap();
bitmap.add(123);
bitmap.add(1258);
bitmap.add(1258);
bitmap.add(2);
bitmap.add(2);
bitmap.add(0);
bitmap.add(0);
bitmap.add(63);
bitmap.add(63);
bitmap.add(64);
bitmap.add(64);
bitmap.add(1);
System.out.println("数组长度为"+bitmap.length);
System.out.println("1111asc======="+bitmap.reallyData.size()+" --"+bitmap.ascOne().size());
bitmap.ascOne().forEach(System.out::print);
System.out.println();
System.out.println("2222asc======="+ bitmap.ascTwo().size());
bitmap.ascTwo().forEach(System.out::print);
System.out.println();
System.out.println("3333desc======="+bitmap.descOne().size());
bitmap.descOne().forEach(System.out::print);
System.out.println();
System.out.println("4444desc======="+bitmap.descTwo().size());
bitmap.descTwo().forEach(System.out::print);
}
}