Java案例如何实现权重排序?

wen java案例 9

本文目录导读:

Java案例如何实现权重排序?

  1. Java权重排序实现方案
  2. 最佳实践建议

Java权重排序实现方案

权重排序的核心思想是为每个元素分配一个权重值,然后根据权重对元素进行排序,以下是几种常见的实现方式:

基础对象排序(实现Comparable接口)

import java.util.*;
// 定义带权重的实体类
class WeightedItem implements Comparable<WeightedItem> {
    private String name;
    private double weight;  // 权重值
    public WeightedItem(String name, double weight) {
        this.name = name;
        this.weight = weight;
    }
    // 实现Comparable接口,定义排序规则(降序排列)
    @Override
    public int compareTo(WeightedItem other) {
        // 降序排列:权重大的排在前面
        return Double.compare(other.weight, this.weight);
    }
    // getter/setter方法
    public String getName() {
        return name;
    }
    public double getWeight() {
        return weight;
    }
    @Override
    public String toString() {
        return String.format("Item{name='%s', weight=%.2f}", name, weight);
    }
}
// 使用示例
public class WeightSortExample1 {
    public static void main(String[] args) {
        List<WeightedItem> items = new ArrayList<>();
        items.add(new WeightedItem("A", 3.5));
        items.add(new WeightedItem("B", 1.2));
        items.add(new WeightedItem("C", 5.8));
        items.add(new WeightedItem("D", 2.1));
        System.out.println("排序前:" + items);
        Collections.sort(items);
        System.out.println("排序后:" + items);
    }
}

使用Comparator进行自定义排序

import java.util.*;
class Item {
    private String id;
    private int priority;     // 优先级权重
    private double score;     // 分数权重
    private Date createTime;  // 时间权重
    public Item(String id, int priority, double score, Date createTime) {
        this.id = id;
        this.priority = priority;
        this.score = score;
        this.createTime = createTime;
    }
    // 计算综合权重(可根据业务需求定制)
    public double getCompositeWeight() {
        return priority * 0.5 + score * 0.3 + (1000 - createTime.getTime() % 1000) * 0.2;
    }
    // getter方法
    public String getId() { return id; }
    public int getPriority() { return priority; }
    public double getScore() { return score; }
    public Date getCreateTime() { return createTime; }
    @Override
    public String toString() {
        return String.format("Item{id='%s', priority=%d, score=%.2f}", 
                           id, priority, score);
    }
}
public class WeightSortExample2 {
    public static void main(String[] args) {
        List<Item> items = new ArrayList<>();
        items.add(new Item("001", 3, 85.5, new Date()));
        items.add(new Item("002", 1, 92.0, new Date(System.currentTimeMillis() - 3600000)));
        items.add(new Item("003", 5, 78.3, new Date(System.currentTimeMillis() - 7200000)));
        items.add(new Item("004", 2, 88.9, new Date(System.currentTimeMillis() - 1800000)));
        System.out.println("排序前:");
        items.forEach(System.out::println);
        // 多权重综合排序
        items.sort(Comparator
            .comparingDouble(Item::getPriority).reversed()  // 优先按优先级降序
            .thenComparingDouble(Item::getScore).reversed() // 再按分数降序
            .thenComparing(Item::getCreateTime)              // 最后按时间升序
        );
        System.out.println("\n排序后:");
        items.forEach(System.out::println);
        // 使用综合权重排序
        items.sort(Comparator.comparingDouble(Item::getCompositeWeight).reversed());
        System.out.println("\n综合权重排序后:");
        items.forEach(System.out::println);
    }
}

随机权重排序(常用于抽奖等场景)

import java.util.*;
class LotteryItem implements Comparable<LotteryItem> {
    private String name;
    private double weight;  // 中奖概率权重
    public LotteryItem(String name, double weight) {
        this.name = name;
        this.weight = weight;
    }
    public String getName() { return name; }
    public double getWeight() { return weight; }
    @Override
    public int compareTo(LotteryItem other) {
        return Double.compare(other.weight, this.weight);
    }
}
public class WeightedRandomSelector {
    private List<LotteryItem> items;
    private double totalWeight;
    private Random random = new Random();
    public WeightedRandomSelector(List<LotteryItem> items) {
        this.items = new ArrayList<>(items);
        this.totalWeight = items.stream()
            .mapToDouble(LotteryItem::getWeight)
            .sum();
    }
    // 按权重随机选择一个元素
    public LotteryItem select() {
        double rand = random.nextDouble() * totalWeight;
        double cumulativeWeight = 0;
        for (LotteryItem item : items) {
            cumulativeWeight += item.getWeight();
            if (rand <= cumulativeWeight) {
                return item;
            }
        }
        // 默认返回最后一个(理论上不会执行到这里)
        return items.get(items.size() - 1);
    }
    // 按权重排序后返回所有元素
    public List<LotteryItem> getSortedItems() {
        List<LotteryItem> sorted = new ArrayList<>(items);
        Collections.sort(sorted);
        return sorted;
    }
    public static void main(String[] args) {
        List<LotteryItem> lotteries = Arrays.asList(
            new LotteryItem("一等奖", 0.1),
            new LotteryItem("二等奖", 0.2),
            new LotteryItem("三等奖", 0.3),
            new LotteryItem("参与奖", 0.4)
        );
        WeightedRandomSelector selector = new WeightedRandomSelector(lotteries);
        // 模拟多次抽奖
        Map<String, Integer> countMap = new HashMap<>();
        for (int i = 0; i < 10000; i++) {
            LotteryItem selected = selector.select();
            countMap.merge(selected.getName(), 1, Integer::sum);
        }
        System.out.println("10000次抽奖结果统计:");
        countMap.forEach((key, value) -> 
            System.out.printf("%s: %d次 (%.2f%%)\n", key, value, value / 100.0));
        System.out.println("\n按权重排序后的奖项:");
        selector.getSortedItems().forEach(item -> 
            System.out.printf("%s (权重: %.2f)\n", item.getName(), item.getWeight()));
    }
}

多维度权重评分排序

import java.util.*;
import java.util.stream.Collectors;
class Product {
    private String name;
    private double salesVolume;     // 销量
    private double rating;          // 评价分数
    private double price;           // 价格(越低越好)
    private double freshness;       // 新鲜度(0-1)
    public Product(String name, double salesVolume, double rating, 
                  double price, double freshness) {
        this.name = name;
        this.salesVolume = salesVolume;
        this.rating = rating;
        this.price = price;
        this.freshness = freshness;
    }
    // 计算综合权重分数(可配置权重系数)
    public double calculateScore(double salesWeight, double ratingWeight, 
                                double priceWeight, double freshnessWeight) {
        // 价格取反(价格越低得分越高)
        double priceScore = 1.0 / (1 + price / 100);
        return salesVolume * salesWeight + 
               rating * ratingWeight + 
               priceScore * priceWeight + 
               freshness * freshnessWeight;
    }
    public String getName() { return name; }
    @Override
    public String toString() {
        return String.format("Product{name='%s', sales=%.0f, rating=%.1f, price=%.2f}", 
                           name, salesVolume, rating, price);
    }
}
public class MultiWeightSorter {
    private double salesWeight = 0.3;
    private double ratingWeight = 0.3;
    private double priceWeight = 0.2;
    private double freshnessWeight = 0.2;
    public MultiWeightSorter() {}
    public MultiWeightSorter(double salesWeight, double ratingWeight, 
                            double priceWeight, double freshnessWeight) {
        this.salesWeight = salesWeight;
        this.ratingWeight = ratingWeight;
        this.priceWeight = priceWeight;
        this.freshnessWeight = freshnessWeight;
    }
    public List<Product> sortProducts(List<Product> products) {
        return products.stream()
            .sorted(Comparator.comparingDouble(
                p -> -p.calculateScore(salesWeight, ratingWeight, 
                                       priceWeight, freshnessWeight)))
            .collect(Collectors.toList());
    }
    public static void main(String[] args) {
        List<Product> products = new ArrayList<>();
        products.add(new Product("手机A", 10000, 4.5, 2999, 0.9));
        products.add(new Product("手机B", 8000, 4.8, 3999, 0.85));
        products.add(new Product("手机C", 15000, 4.2, 1999, 0.7));
        products.add(new Product("手机D", 12000, 4.6, 2499, 0.95));
        System.out.println("排序前:");
        products.forEach(System.out::println);
        MultiWeightSorter sorter = new MultiWeightSorter(0.4, 0.3, 0.2, 0.1);
        List<Product> sortedProducts = sorter.sortProducts(products);
        System.out.println("\n排序后(销量权重0.4,评价权重0.3,价格权重0.2,新鲜度权重0.1):");
        sortedProducts.forEach(System.out::println);
    }
}

最佳实践建议

  1. 选择合适的排序方式

    • 单一权重:实现Comparable接口
    • 多权重排序:使用Comparator链式调用
    • 随机权重选择:使用概率累加算法
  2. 性能优化注意事项

    • 对于大型数据集,考虑使用parallelStream()进行并行处理
    • 避免在排序过程中频繁计算权重值
    • 如果需要保持有序状态,使用TreeSetPriorityQueue
  3. 权重归一化处理

    • 确保不同量级的权重能够合理比较
    • 可以对原始数据进行归一化处理(如:z-score标准化、min-max标准化)
  4. 实际应用场景

    • 搜索引擎结果排序
    • 推荐系统物品排序
    • 任务优先级调度
    • 广告竞价排名
    • 游戏道具概率抽取

选择哪种实现方式取决于你的具体业务需求和数据规模。

抱歉,评论功能暂时关闭!