IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> JAVA与JavaScript递增ID压缩与解压 -> 正文阅读

[JavaScript知识库]JAVA与JavaScript递增ID压缩与解压

上周代码分享中的一个代码,因业务需要要将一组数据库自增的id, 思路就是将id排序,取最小的为基数, 取剩下所有数与基数的差值 新建一个数组将差值的下标改为1 其他默认为0 将这个数组 拆分4个一组 转换为16进制 .
压缩效果如下:

压缩后 = 10zd3e9fffffffffffffffffffffffc
ID个数 = 104
解压后 = [10,11,13,16,17,18,19,20,22,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119]

JAVA实现


package com.example.demo.utils;

import cn.hutool.core.util.ArrayUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.LongSummaryStatistics;
import java.util.stream.Collectors;

/**
 * 一组压缩算法的ID
 * <br/>
 * 类似 10,12,13,33这种类似递增的Id  相差不要太大
 *
 * @author zhangqi
 * @date 2022/5/4 18:09
 */
public final class CompressionIdUtil {
    private CompressionIdUtil() {
    }

    /**
     * 分隔符
     */
    public static final String SEPARATOR = "z";

    /**
     * 压缩算法ID
     *
     * @param ids 压缩ID
     * @return 压缩后
     */
    public static String compression(long... ids) {
        if (ArrayUtil.isEmpty(ids)) {
            return "";
        }
        LongSummaryStatistics arrResult = Arrays.stream(ids.clone()).distinct().sorted().summaryStatistics();
        long count = arrResult.getCount();
        long minId = arrResult.getMin();
        if (count == 1) {
            return minId + SEPARATOR + 1;
        }
        long maxId = arrResult.getMax();
        long[] newIds = new long[(int) (Math.ceil(Math.max((((int) (maxId - minId)) >> 3) + 1, 1)) * 8)];
        Arrays.stream(ids).forEach(id -> newIds[(int) (id - minId)] = 1);
        List<String> compressionList = Arrays.stream(newIds).mapToObj(String::valueOf).collect(Collectors.toList());
        return minId + SEPARATOR + Lists.partition(compressionList, 4).stream()
                .map(item -> Integer.toString(Integer.parseInt(String.join("", item), 2), 16))
                .collect(Collectors.joining());
    }

    /**
     * 解压ID
     *
     * @param compressionStr 压缩后的ID
     * @return 解压ID后
     */
    public static List<Long> unpack(String compressionStr) {
        if (StringUtils.isBlank(compressionStr)) {
            return Collections.emptyList();
        }
        String[] strArr = compressionStr.split(SEPARATOR);
        if (strArr.length != 2) {
            return Collections.emptyList();
        }
        String baseId = strArr[0];
        char[] chars = strArr[1].toCharArray();
        long id = Long.parseLong(baseId);
        if (chars.length == 1) {
            return Collections.singletonList(id);
        }
        StringBuilder compression = new StringBuilder();
        for (char aChar : chars) {
            compression.append(StringUtils.leftPad(Integer.toString(Integer.parseInt(String.valueOf(aChar), 16), 2), 4, "0"));
        }
        List<Long> resultList = Lists.newArrayListWithCapacity(compressionStr.length() >> 2);
        for (int i = 0; i < compression.toString().toCharArray().length; i++) {
            if (compression.toString().toCharArray()[i] == '1') {
                resultList.add(id + i);
            }
        }
        return resultList;
    }


    public static void main(String[] args) {
        String compression = compression(10, 16, 11, 13, 17, 18, 19, 20, 22, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119);
        System.out.println("compression = " + compression);
        List<Long> unpack = unpack(compression);
        int size = unpack.size();
        System.out.println("size = " + size);
        String s = JSONObject.toJSONString(unpack);
        System.out.println("s = " + s);
    }
}

JS实现

 const byteToHex = (s) => {
        const r = parseInt(s, 2).toString(16);
        return r;
    };
    //16进制重新变成2进制
    const hexToByte = (s) => {
        const r = parseInt(s, 16).toString(2);
        return r;
    };

    //压缩
    export const arrayToStr = (arr) => {
        arr.sort(function (a, b) {
            return +a - +b;
        });
        const baseId = arr[0];
        const indexArr = arr.map((o) => +o - +baseId);
        const len = +indexArr[indexArr.length - 1] + 1;
        const newArr = new Array(Math.ceil(len / 8) * 8).fill(0); //每8位为一个字节,不足的补0
        indexArr.forEach((o) => (newArr[+o] = 1));
        let strArr = Array(newArr.length / 4)
            .fill(0)
            .map((o) => (o = newArr.splice(0, 4).join('')));
        let data = strArr.map((o) => byteToHex(o)).join('');
        return `${data}z${baseId}`;
    };


    //解码
    export const strToArray = (s) => {
        let baseId = s.substr(s.indexOf('z') + 1);
        let strArr = s.substr(0, s.indexOf('z'));
        let arr = strArr.split('');
        let m = new Array(arr.length).fill(0).map((o) => hexToByte(arr.splice(0, 1)));
        let newArr = m
            .map((o) => o.padStart(4, '0'))
            .join('')
            .split('');
        let indexArr = [];
        newArr.forEach((o, i) => o === '1' && indexArr.push(i));
        indexArr = indexArr.map((o) => `${String(+baseId + o)}`);
        return indexArr;
    };
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-06 10:58:49  更:2022-05-06 11:00:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:30:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码