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. leetcode:283. Move Zeroes(Java)解答

    转载请注明出处:z_zhaojun的博客 原文地址:http://blog.csdn.net/u012975705/article/details/50493772 题目地址:https://leet ...

  2. JavaScript操作符(关系操作符、相等操作符和条件操作符)

    关系操作符用于对两个值进行比较,返回一个布尔值.关系操作符包括大于(>),小于(<),大于等于(>=),小于等于(<=).当关系操作符用于非数值时,也要先进行数值的转换.如 v ...

  3. 【iOS系列】-程序开启后台运行

    [iOS系列]-程序开启后台运行 iOS程序是伪后台的运行,可是有时候我们需要让其在后台也要进行一些操作,我们可以让其伪装成音乐的APP,这样就可以让程序后台进行相关操作了,具体做法如下: 1:在Ap ...

  4. 【CTF】后续深入学习内容

    1.i春秋 https://www.ichunqiu.com/course/451 搜索black hat,可以看到黑帽大会的内容.免费. 2.wireshark 基础篇 1)由于Wireshark是 ...

  5. shell脚本常用(记)

    1.变量检查,判空 a.直接变量判断  if [ ! $1 ];then ..empty..fi b.变量通过" "引号引起来  if [ ! -n "$1" ...

  6. (转载)synchronized代码块

    原文:http://blog.csdn.net/luoweifu/article/details/46613015 作者:luoweifu 转载请标名出处 <编程思想之多线程与多进程(1)——以 ...

  7. ionic 和cordova的区别是什么

    很多新朋友ionic基础教程都学完了,还是不知道ionic 和cordova 是什么关系 ionic是什么: Ionic(ionicframework)一款开源的Html5移动App开发框架,是Ang ...

  8. wpa_supplicant drivers 查看跟踪

    /**************************************************************************** * wpa_supplicant drive ...

  9. hash学习

    hash真奇妙 1.子串hash:如果我们要求一段子串的hash值,设h[i]:1-i的hash值,h[l-r]=h[r]-h[l-1]*pw[r-l+1],无论是模意义下还是自然溢出都是可以的 2. ...

  10. 解决weblogic页面和控制台乱码问题

    转自:https://blog.csdn.net/u010995831/article/details/53283746 之前一直有碰到weblogic各种乱码问题,要不就是页面乱码,要不就是控制台乱 ...