Bitmap,今天我们来分析一下bitmap的实现原理以及它的使用场景。

一、使用场景:

  1、对于大量数据(几千个数据的就不要在废话了),且无重复或者可以忽略重复的数字。为啥这里要强调无重复,因为在bitmap实现过程中再试无法处理。

  2、用于查询新数字是存在在已知数据中。(如果用于全量打印之类的,循环性能上没有太大优势,内存空间上会有一定的优势)

  3、查询速度能控制在1级别(what?难道连一次循环都不需要吗?是的,都不需要循环,都不需要循环,都不需要循环,重要的事情强调三次。)

二、实现原理

  理论实现方案1:

    结构 List<Integer> datas;

    boolean contains(Integer i){ for循环获取}

    结论:Integer 由一个 Integer是一个Class对象,(使用Java的银都知道,炒鸡占用内存啊,过儿……)

    楼主:这得多少内存啊,容我仔细算算……

  理论实现方案2:

    结构 List<int> datas;

    boolean contains(int i){for 循环获取}

    结论:int 对 Integer 说:老弟,每个对象只需要4个字节即(32位)就够了,比你少了好多内存啊。

    楼主:那你contains还要for循环,你这是O1,O1,O1 没听懂啊。(过儿……)

  理论实现方案3:

    结构 int [] datas;

    boolean contains(int i){

      if(datas[i] == 1) {return true;}

      else{ return false;}

    }

    结论:利用下标的方式可以快速的获取数组中对应下标的值,如果为1 则表示存在,否则表示不存在。

    缺点:一开始就需要初始化一个超级无敌大的数组

    楼主:嗯,不错不错,给你点赞,查询不需要循环了。你比楼上的强多了。不过 一个int 4个字节 32位,如果最大值为 1000,000,000  那还是需要很多内存啊。

    4000,000,000字节 = 3814MB ,这个……

  理论实现方案4:

    结构 int[] datas;

    boolean contains(int i){ return "请参考具体实现……"}

    楼主:你这个不是和上面的涨的一样吗,难道你想抄袭吗^_^

    过儿:虽然长得像,可是内在不一样啊。请听我细细说来……

    结论:一个int 4个字节 32位,方案3中,每个int只保存一个int值,我这个一个int 利用每一位进行保存一个int值,一个int可以保存32个值,内存只用1/32。厉害吧……

      如果最大值为 1000,000,000   即 125,000,000字节 = 120MB

    优点:利用每一个位进行保存一个数字,内存消耗可以大幅度的降低。

    楼主:那你来实现一下。666~~~

三、Java 实现

public class BitMap {

    private int[] datas;
private int m = 31; // 0-31 个位数 BitMap(int max) {
int count = (max >> 5) + 1;
datas = new int[count];
System.out.println("datas.length:"+datas.length);
}
// 添加
void add(int i) {
int c = i >> 5; // 计算在那个datas下标中
int k = i & m; // 计算标记位k
int d = datas[c];
d = d | (1 << k); // 标记k位 值为 1
datas[c] = d;
}
// 查询
boolean contains(int i) {
int c = i >> 5; // 计算在按个datas下标中
int k = i & m; // 计算标记位k
int d = datas[c];
int n = d >> k & 1; // 获取第K位的标记值
if (n == 1) {
return true;
} else {
return false;
}
} public static void main(String[] args) {
BitMap m = new BitMap(1000000000); m.add(39491);
m.add(15157);
m.add(26304);
m.add(19857);
m.add(17881);
m.add(16593);
m.add(478);
m.add(8398);
m.add(2011); //
m.add(23134); // System.out.println("23134:"+m.contains(23134));
System.out.println("2011:"+m.contains(2011));
System.out.println("152:"+m.contains(152)); } }

运行结果:

datas.length:31250001
23134:true
2011:true
152:false

计算内存消耗:

     System.gc();
long total = Runtime.getRuntime().totalMemory(); // byte
long m1 = Runtime.getRuntime().freeMemory();
System.out.println("before:" + (total - m1)); BitMap m = new BitMap(1000000000); long total1 = Runtime.getRuntime().totalMemory();
long m2 = Runtime.getRuntime().freeMemory();
System.out.println("after:" + (total1 - m2)); long u= (total1 - m2) - (total - m1); // byte System.out.println("used:"+u/1024/1024+"M");

before:1958784
after:126958808
used:119M

简单实现了一下BitMap , 本例只用于学习使用。根据上面的代码可以看出,保存最大值为 1,000,000,000 的值,只需要 31250001个int 即 119MB

深入学习数据结构之bitmap(四)的更多相关文章

  1. Redis学习——数据结构介绍(四)

    一.简介 作为一款key-value 的NoSQL数据库,Redis支持的数据结构比较丰富,有:String(字符串) .List(列表) .Set(集合) .Hash(哈希) .Zset(有序集合) ...

  2. 20172328《程序设计与数据结构》实验四 Android程序设计报告

    20172328<程序设计与数据结构>实验四 Android程序设计报告 课程:<程序设计与数据结构> 班级: 1723 姓名: 李馨雨 学号:20172328 实验教师:王志 ...

  3. 一种很有意思的数据结构:Bitmap

    昨晚遇到了一种很有意思的数据结构,Bitmap. Bitmap,准确来说是基于位的映射.其中每个元素均为布尔型(0 or 1),初始均为 false(0).位图可以动态地表示由一组无符号整数构成的集合 ...

  4. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第四章:Direct 3D初始化

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第四章:Direct 3D初始化 学习目标 对Direct 3D编程在 ...

  5. 从一道高大上的面试题来学习位图算法BitMap

    今天我偶然刷到了一篇文章,"华为二面:一个文件里面有5亿个数据,一行一个,没有重复的,进行排序".不知道又是哪个无良媒体瞎起的标题,夺人眼球. 不过说归说,这题听着就很高大上,5亿 ...

  6. 我的MYSQL学习心得(十四) 备份和恢复

    我的MYSQL学习心得(十四) 备份和恢复 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) ...

  7. SqList *L 和 SqList * &L的区别/学习数据结构突然发现不太懂 小祥我查找总结了一下

    小祥在学习李春葆的数据结构教程时发现一个小问题,建立顺序表和输出线性表,这两个函数的形参是不一样的. 代码在这里↓↓↓ //定义顺序表L的结构体 typedef struct { Elemtype d ...

  8. 【Unity Shaders】学习笔记——SurfaceShader(四)用纹理改善漫反射

    [Unity Shaders]学习笔记——SurfaceShader(四)用纹理改善漫反射 转载请注明出处:http://www.cnblogs.com/-867259206/p/5603368.ht ...

  9. OpenGL学习之路(四)

    1 引子 上次读书笔记主要是学习了应用三维坐标变换矩阵对二维的图形进行变换,并附带介绍了GLSL语言的编译.链接相关的知识,之后介绍了GLSL中变量的修饰符,着重介绍了uniform修饰符,来向着色器 ...

随机推荐

  1. 抓包工具Fiddler使用宝典之捕获手机报文

    Fiddler 是通过代理来实现数据捕获的.对 Android 手机来说,也是通过将网络连接的代理指向 PC 机的 Fiddler port.来实现数据包的拦截. 以下,我以我的一次实践为例,向大家介 ...

  2. 图像配准建立仿射变换模型并用RANSAC算法评估

    当初选方向时就由于从小几何就不好.缺乏空间想像能力才没有选择摄影測量方向而是选择了GIS. 昨天同学找我帮他做图像匹配.这我哪里懂啊,无奈我是一个别人有求于我,总是不好意思开口拒绝的人.于是乎就看着他 ...

  3. 2016/4/7 datatype:①json ②XML

    ①JSON 1,postjsonxml.php     json用循环方式处理传来的值  for(key in data) for(var i=0;i<data.length;i++){data ...

  4. ajax跨域问题解决(spring boot)

    之前用的服务器响应头部添加Access-Control-Allow-Origin: *来解决的 public static void setResp(HttpServletResponse resp) ...

  5. touch all contents in a folder recursively

    https://superuser.com/questions/598163/powershell-touch-all-files-newer-than Powershell to use Unix ...

  6. Can't remove netstandard folder from output path (.net standard)

    https://developercommunity.visualstudio.com/content/problem/30940/cant-remove-netstandard-folder-fro ...

  7. DOM方式解析xml实例2

    老样子,javabean实体类: import java.io.*; public class Book implements Serializable { private int id; priva ...

  8. C++在循环内和循环外定义变量的差异

    原文:http://blog.csdn.net/cashey1991/article/details/45127561 最后总结: 对于使用int等基本数据类型作为循环变量,只要你用的优化方面足够给力 ...

  9. BZOJ_3172_[Tjoi2013]单词_AC自动机

    BZOJ_3172_[Tjoi2013]单词_AC自动机 Description 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. ...

  10. 《JAVA与模式》之责任链模式

    责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链上的哪一个 ...