首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 權重隨機分發器實作範例

     編輯:Java 相關知識

前言

在開發過程中,常會遇到需要根據指定機率執行不同邏輯的場景。例如:20% 執行方法 A、1% 執行方法 B、29% 執行方法 C、50% 執行方法 D。若直接使用 if-else 搭配隨機數判斷,程式碼不僅冗長,還難以維護擴展。本文介紹一個通用的 RandomDispatcher 類別,讓權重分發邏輯變得簡潔優雅。

核心設計思路

分發器內部維護一個「權重-索引」映射表。隨機時產生一個 0 到總權重之間的數值,遍歷累加權重區間,落在哪個區間就回傳對應的索引。這樣無需硬編碼機率邏輯,新增或調整權重只需修改配置。

完整程式碼實作

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class RandomDispatcher {
    private final List<WeightEntry> entries = new ArrayList<>();
    private int totalWeight = 0;
    private final Random random = new Random();

    /** 內部靜態類別:封裝權重與業務索引 */
    private static class WeightEntry {
        int weight;
        int index;
        WeightEntry(int weight, int index) {
            this.weight = weight;
            this.index = index;
        }
    }

    /** 新增一個權重項目
     * @param weight 權重值(不需加總為 100)
     * @param index  業務邏輯對應的索引碼
     */
    public void put(int weight, int index) {
        if (weight <= 0) return;
        entries.add(new WeightEntry(weight, index));
        totalWeight += weight;
    }

    /** 執行隨機分發,回傳對應的索引碼 */
    public int random() {
        if (entries.isEmpty()) return -1;
        int r = random.nextInt(totalWeight); // 0 ~ totalWeight-1
        int cumulative = 0;
        for (WeightEntry e : entries) {
            cumulative += e.weight;
            if (r < cumulative) return e.index;
        }
        return entries.get(entries.size() - 1).index; // 兜底
    }
}

使用範例

public class Demo {
    public static void main(String[] args) {
        RandomDispatcher dispatcher = new RandomDispatcher();
        // 配置權重:索引 1~4 分別代表四種業務
        dispatcher.put(20, 1); // 20% -> A
        dispatcher.put(1,  2); // 1%  -> B
        dispatcher.put(29, 3); // 29% -> C
        dispatcher.put(50, 4); // 50% -> D

        // 模擬 10 次分發
        for (int i = 0; i < 10; i++) {
            int idx = dispatcher.random();
            switch (idx) {
                case 1: System.out.println("執行方法 A"); break;
                case 2: System.out.println("執行方法 B"); break;
                case 3: System.out.println("執行方法 C"); break;
                case 4: System.out.println("執行方法 D"); break;
                default: System.out.println("無匹配邏輯");
            }
        }
    }
}

優勢總結

  • 解耦:業務邏輯與機率配置完全分離。
  • 擴展性:新增選項只需一行 put(),無須修改核心演算法。
  • 可讀性:權重意圖一目瞭然,維護成本極低。

此模式廣泛適用於遊戲掉落、廣告輪播、A/B 測試流量分發等場景,建議收藏備用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved