基于比特位图映射对List<Object>多维度排序

简介:程序实现了基于位图编码的多维度商品排序。代码将商品的四个维度(置顶、学生专享、排序值、库存)编码到一个64位长整型中,通过数值比较实现复合排序。

主要特点:

  1. 创新编码方案‌:使用位运算将布尔值和整数统一编码,最高位表示置顶,次高位表示学生专享
  2. 优先级保证‌:编码结构确保isTop > isStudent > sort > store的优先级顺序
  3. 性能优化‌:一次编码后使用快速排序,适合大规模数据
  4. 结果验证‌:与传统比较器方法对比,确保排序正确性
  5. 可扩展性‌:编码方案可以轻松调整各字段的位数分配

这种方法结合了位图排序的思想,同时解决了多维度排序的复杂性问题。

java 复制代码
/**
 * 商品实体类
 */
class Product {
    private String name;
    private Integer sort;      // 排序字段
    private Integer store;     // 库存
    private Boolean isTop;     // 是否置顶
    private Boolean isStudent; // 是否学生专享

    public Product(String name, Integer sort, Integer store, Boolean isTop, Boolean isStudent) {
        this.name = name;
        this.sort = sort;
        this.store = store;
        this.isTop = isTop;
        this.isStudent = isStudent;
    }

    public String getName() { return name; }
    public Integer getSort() { return sort; }
    public Integer getStore() { return store; }
    public Boolean getIsTop() { return isTop; }
    public Boolean getIsStudent() { return isStudent; }

    @Override
    public String toString() {
        return String.format("商品:%-8s 置顶:%-5s 学生:%-5s 排序值:%-3d 库存:%-3d", 
            name, isTop, isStudent, sort, store);
    }
}

/**
 * 基于位图编码的商品排序器
 */
class ProductBitmapSorter {
    // 位分配方案(从高位到低位)
    private static final int TOP_BIT_SHIFT = 60;      // 1位: 置顶标识
    private static final int STUDENT_BIT_SHIFT = 58;  // 1位: 学生专享标识
    private static final int SORT_BIT_SHIFT = 40;     // 18位: 排序字段
    private static final int STORE_BIT_SHIFT = 20;    // 20位: 库存字段
    
    /**
     * 将商品的多维属性编码为一个长整型
     * 编码格式:[1位置顶][1位学生][18位排序值][20位库存]
     */
    public static long encodeProduct(Product product) {
        long encoded = 0L;
        
        // 置顶标识(最高位)
        if (Boolean.TRUE.equals(product.getIsTop())) {
            encoded |= (1L << TOP_BIT_SHIFT);
        }
        
        // 学生专享标识
        if (Boolean.TRUE.equals(product.getIsStudent())) {
            encoded |= (1L << STUDENT_BIT_SHIFT);
        }
        
        // 排序字段(限制在0-262143范围内)
        int sortValue = Math.min(Math.max(product.getSort(), 0), 262143);
        encoded |= ((long) sortValue) << SORT_BIT_SHIFT;
        
        // 库存字段(限制在0-1048575范围内)
        int storeValue = Math.min(Math.max(product.getStore(), 0), 1048575);
        encoded |= ((long) storeValue) << STORE_BIT_SHIFT;
        
        return encoded;
    }
    
    /**
     * 使用位图编码进行排序
     */
    public static void sortProductsWithBitmap(List<Product> products) {
        // 创建编码映射
        Map<Long, Product> encodedMap = new HashMap<>();
        List<Long> encodedValues = new ArrayList<>();
        
        // 编码所有商品
        for (Product product : products) {
            long encoded = encodeProduct(product);
            encodedMap.put(encoded, product);
            encodedValues.add(encoded);
        }
        
        // 对编码值进行排序(自然降序)
        Collections.sort(encodedValues, Collections.reverseOrder());
        
        // 清空原列表并按排序后的编码重新填充
        products.clear();
        for (Long encoded : encodedValues) {
            products.add(encodedMap.get(encoded));
        }
    }
    
    /**
     * 传统的比较器排序(用于对比验证)
     */
    public static void sortProductsTraditional(List<Product> products) {
        Collections.sort(products, (p1, p2) -> {
            // 第一优先级: isTop (置顶的排在前面)
            int topCompare = Boolean.compare(p2.getIsTop(), p1.getIsTop());
            if (topCompare != 0) return topCompare;
            
            // 第二优先级: isStudent (学生专享排在前面)
            int studentCompare = Boolean.compare(p2.getIsStudent(), p1.getIsStudent());
            if (studentCompare != 0) return studentCompare;
            
            // 第三优先级: sort字段 (数值大的排在前面)
            int sortCompare = Integer.compare(p2.getSort(), p1.getSort());
            if (sortCompare != 0) return sortCompare;
            
            // 第四优先级: store库存 (库存多的排在前面)
            return Integer.compare(p2.getStore(), p1.getStore());
        });
    }
    
    /**
     * 解码长整型为可读格式(用于调试)
     */
    public static String decodeProduct(long encoded) {
        boolean isTop = ((encoded >> TOP_BIT_SHIFT) & 1) == 1;
        boolean isStudent = ((encoded >> STUDENT_BIT_SHIFT) & 1) == 1;
        int sortValue = (int) ((encoded >> SORT_BIT_SHIFT) & 0x3FFFF); // 18位掩码
        int storeValue = (int) ((encoded >> STORE_BIT_SHIFT) & 0xFFFFF); // 20位掩码
        
        return String.format("置顶:%-5s 学生:%-5s 排序值:%-6d 库存:%-6d", 
            isTop, isStudent, sortValue, storeValue);
    }
}

/**
 * 演示主类
 */
public class ProductBitmapSort {
    public static void main(String[] args) {
        // 创建测试商品数据
        List<Product> products = Arrays.asList(
            new Product("商品A", 10, 100, false, true),
            new Product("商品B", 20, 50, true, false),
            new Product("商品C", 15, 200, true, true),
            new Product("商品D", 25, 80, false, false),
            new Product("商品E", 10, 150, false, true),
            new Product("商品F", 30, 300, false, false),
            new Product("商品G", 5, 60, true, false)
        );
        
        System.out.println("=== 原始商品列表 ===");
        printProducts(products);
        
        // 方法1: 位图编码排序
        List<Product> bitmapSorted = new ArrayList<>(products);
        ProductBitmapSorter.sortProductsWithBitmap(bitmapSorted);
        System.out.println("\n=== 位图编码排序结果 ===");
        printProducts(bitmapSorted);
        
        // 方法2: 传统比较器排序(用于验证)
        List<Product> traditionalSorted = new ArrayList<>(products);
        ProductBitmapSorter.sortProductsTraditional(traditionalSorted);
        System.out.println("\n=== 传统比较器排序结果 ===");
        printProducts(traditionalSorted);
        
        // 验证两种方法结果是否一致
        boolean isSame = true;
        for (int i = 0; i < bitmapSorted.size(); i++) {
            if (!bitmapSorted.get(i).getName().equals(traditionalSorted.get(i).getName())) {
                isSame = false;
                break;
            }
        }
        System.out.println("\n=== 排序验证 ===");
        System.out.println("位图排序与传统排序结果是否一致: " + isSame);
        
        // 显示编码示例
        System.out.println("\n=== 编码示例 ===");
        for (Product product : products) {
            long encoded = ProductBitmapSorter.encodeProduct(product);
            System.out.println(product.getName() + " -> 编码值: " + encoded + 
                " -> 解码: " + ProductBitmapSorter.decodeProduct(encoded));
        }
    }
    
    private static void printProducts(List<Product> products) {
        for (int i = 0; i < products.size(); i++) {
            System.out.println((i + 1) + ". " + products.get(i));
        }
    }
}

总结:

相对于传统的javaAPI排序,性能优化在50%左右。循环越多,维度越多,优化效果越明显;

相关推荐
如此这般英俊8 小时前
手搓Claude Code-第六章 subagent
数据结构·人工智能·python·语言模型·自然语言处理
Tairitsu_H9 小时前
[LC优选算法#17] 链表 | 合并 K 个升序链表 | K个⼀组翻转链表
数据结构·算法·链表
zwenqiyu12 小时前
非线性字符串数据结构串讲
数据结构·c++·学习·算法
东华万里13 小时前
第32篇 数据结构入门 单链表的增删查改实现
数据结构·链表
OOJO15 小时前
哈希表实现
数据结构·哈希算法·散列表
2501_9437823318 小时前
【共创季稿事节】鸿蒙原生 ArkTS 布局实现 Column + List + Navigation 协作导航 — 从列表渲染到页面切换的完整实践
学习·华为·list·harmonyos·鸿蒙
剑挑星河月18 小时前
234. 回文链表
java·数据结构·算法·leetcode·链表
六bring个六18 小时前
链表学习(常规链表)
数据结构·学习·链表
tachibana21 天前
hot100 回文链表(234)
java·网络·数据结构·leetcode·链表
aaaameliaaa1 天前
进制练习题【找出只出现一次的数字、交换两个变量(不创建临时变量)、统计二进制中1的个数、打印整数二进制的奇数位和偶数位、求两个数二进制中不同位的个数】
c语言·数据结构·笔记·算法