一、问题引入
假设QQ音乐服务器上有9000万首音乐,用户按照歌名来搜索歌曲,如何使得满足这一需求所需的数据占用的内存空间最小以及用户搜索歌曲速度更快
二、分析问题
1、为了满足使得数据占用的内存更小,可以采用映射的思路,按照某种规则对歌名建立对应的索引,将索引存放在内存空间中,将音乐存放在外部存储器中(硬盘、磁带、光盘)。一方面,只在内存中存放索引,将会减小内存的使用;另一方面,通过索引进行查找要比直接扫描文件进行查找速度更快
2、那么在内存空间中应该使用什么数据结构来存储索引呢?
(1)如果使用int[]数组存储9000万个索引,将会占用0.355GB的内存空间,占用的内存空间较大
(2)但是如果使用int类型的字节上的位为0或者为1来用对应位置上的索引来表示所存储的数字,这将会极大地降低对内存的占用
举例:1个Byte有8个bit,索引位置为5、2、1的位置bit位为1,因此该Byte存储了5、2、1三个数字,Java中二进制的最高位为符号位,不能够进行使用
(3)1个int有32个bit,其中31个bit的状态可用来存储31个数字,那么存储索引所需的内存空间将会变为原来的1/31,即为0.011GB
三、解决问题
Java中的BitSet
1、BitSet中的添加、删除、判断方法
public class BitSetTest {
public void test(){
int a = 1;// 00000000 00000000 00000000 00000001
a = a | 2;// 00000000 00000000 00000000 00000011
System.out.println(Integer.toBinaryString(a));// 将int数字转为2进制String字符串
}
public static void main(String[] args) {
new BitSetTest().test();
// 使用BitSet存放50之内的所有偶数
BitSet bitSet = new BitSet(51);// 初始化容量,即使用多少个bit
for (int i = 0; i <= 50; i++) {
if(i % 2 == 0){
bitSet.set(i);// 为数字i分配bit并将bit状态调整为1
}
}
System.out.println(bitSet);
System.out.println(bitSet.get(48));// 判断bitSet中是否存在数字48
bitSet.clear(48);// 从bitSet中删除数字48
System.out.println(bitSet.get(48));// 判断bitSet中是否存在数字48
}
}
四、涉及知识
1、数据结构解决的是数据的存储问题;算法解决的是利用数据结构更好地做一些事情的问题
2、使用递归比使用循环效率低(速度慢、占用内存空间大)是因为递归每次到下一层时都需要使用内存做临时记录
3、BitSet的本质原理是利用位的状态(0和1)来映射所存储的数
4、滑动窗体本质上就是一种特殊的双层循环