Java之大数据位图法(无重复排序,重复排序,去重复排序,数据压缩)

Posted smallji

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java之大数据位图法(无重复排序,重复排序,去重复排序,数据压缩)相关的知识,希望对你有一定的参考价值。

大数据位图法(无重复排序,重复排序,去重复排序,数据压缩)之Java实现

 

位图法介绍

    位图的基本概念是用一个位(bit)来标记某个数据的存放状态,由于采用了位为单位来存放数据,所以节省了大量的空间。举个具体的例子,在Java中一般一个int数字要占用32位,如果能用一位就表示这个数,就可以缩减大量的存储空间。一般把这种方法称为位图法,即Bitmap。

    位图法比较适合于判断是否存在这样的问题,元素的状态比较少,元素的个数比较多的情况之下。那么具体咋么做呢,这样,非常简单明了就是,2.5亿个整数里面,我维护一个长度等于最大整数值得字符串,每个整数是否存在我就在该整数对应的位置置为1,比如,有{2, 4, 5, 6, 67, 5}这么几个整数,我维护一个 00…0000 67位的字符串。但是,如果你不知道整数的最大值,你至少需要一个长度2^32的字符串,因为整数的最大值就是2^32,(int占4个字节,因此是32位),那这就最少是512M内存,从char的长度算内存会算吧,直接、最大整数/8*2^20 就是M的单位。那这么说来就可以理解位图法了。

BitSet

    正因为位图运算在空间方面的优越性,很多语言都有直接对它的支持。如在C++的STL库中就有一个bitset容器。而在Java中,在java.util包下也有一个BitSet类用来实现位图运算。此类实现了一个按需增长的位向量。BitSet的每一位都由一个boolean值来表示。用非负的整数将BitSet的位编入索引,可以对每个编入索引的位进行测试、设置或者清除。通过逻辑与、逻辑或和逻辑异或操作,可以使用一个BitSet修改另一个BitSet的内容。

    需要注意的是BitSet底层实现是通过一个long数组来保存数据的,也就是说它增长的最小单位是一个long所占的逻辑位,即64位。但如果不是对存储区空间有极致的要求,而且对自己的基本功非常有信心,不建议自己去实现一个跟BitSet类似的类来实现相关的功能。因为jdk中的类都是极精简并做过合理优化的,BitSet类比较长。

无重复排序

java JDK里面容器类的排序算法使用的主要是插入排序和归并排序,可能不同版本的实现有所不同,关键代码如下:

 1 /**
 2      * Performs a sort on the section of the array between the given indices
 3      * using a mergesort with exponential search algorithm (in which the merge
 4      * is performed by exponential search). n*log(n) performance is guaranteed
 5      * and in the average case it will be faster then any mergesort in which the
 6      * merge is performed by linear search.
 7      * 
 8      * @param in -
 9      *            the array for sorting.
10      * @param out -
11      *            the result, sorted array.
12      * @param start
13      *            the start index
14      * @param end
15      *            the end index + 1
16      */
17     @SuppressWarnings("unchecked")
18     private static void mergeSort(Object[] in, Object[] out, int start,
19             int end) {
20         int len = end - start;
21         // use insertion sort for small arrays
22         if (len <= SIMPLE_LENGTH) {
23             for (int i = start + 1; i < end; i++) {
24                 Comparable<Object> current = (Comparable<Object>) out[i];
25                 Object prev = out[i - 1];
26                 if (current.compareTo(prev) < 0) {
27                     int j = i;
28                     do {
29                         out[j--] = prev;
30                     } while (j > start
31                             && current.compareTo(prev = out[j - 1]) < 0);
32                     out[j] = current;
33                 }
34             }
35             return;
36         }
37         int med = (end + start) >>> 1;
38         mergeSort(out, in, start, med);
39         mergeSort(out, in, med, end);
40 
41         // merging
42 
43         // if arrays are already sorted - no merge
44         if (((Comparable<Object>) in[med - 1]).compareTo(in[med]) <= 0) {
45             System.arraycopy(in, start, out, start, len);
46             return;
47         }
48         int r = med, i = start;
49 
50         // use merging with exponential search
51         do {
52             Comparable<Object> fromVal = (Comparable<Object>) in[start];
53             Comparable<Object> rVal = (Comparable<Object>) in[r];
54             if (fromVal.compareTo(rVal) <= 0) {
55                 int l_1 = find(in, rVal, -1, start + 1, med - 1);
56                 int toCopy = l_1 - start + 1;
57                 System.arraycopy(in, start, out, i, toCopy);
58                 i += toCopy;
59                 out[i++] = rVal;
60                 r++;
61                 start = l_1 + 1;
62             } else {
63                 int r_1 = find(in, fromVal, 0, r + 1, end - 1);
64                 int toCopy = r_1 - r + 1;
65                 System.arraycopy(in, r, out, i, toCopy);
66                 i += toCopy;
67                 out[i++] = fromVal;
68                 start++;
69                 r = r_1 + 1;
70             }
71         } while ((end - r) > 0 && (med - start) > 0);
72 
73         // copy rest of array
74         if ((end - r) <= 0) {
75             System.arraycopy(in, start, out, i, med - start);
76         } else {
77             System.arraycopy(in, r, out, i, end - r);
78         }
79     }

 

下面我们说下位图法排序的思路:其实思路开篇已经交代,为了让大家更容易理解,我将通过举例的方式进一步阐明,假设我们有一个不重复的整型序

 

以上是关于Java之大数据位图法(无重复排序,重复排序,去重复排序,数据压缩)的主要内容,如果未能解决你的问题,请参考以下文章

对大数据量进行排序--位图法

Java 字符串去重

Java难点攻克「海量数据计算系列」如何使用BitMap在海量数据中对相应的进行去重查找和排序实战

mysql语句,分组去重,排序问题

java数据结构与算法之最长无重复子串问题

java数据结构与算法之最长无重复子串问题