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

J2ME 隨機數生成全攻略:Random 類完整用法與指定範圍整數實戰技巧

     編輯:J2ME

核心差異:J2ME 無 Math.random()

J2SE 常用 Math.random() 產生 [0.0, 1.0) double,但 CLDC/MIDP 精簡了 Math 類,移除 random()。J2ME 統一使用 java.util.Random 產生偽隨機數。

Random 類核心用法

建構子與種子


// 1. 預設種子 = System.currentTimeMillis() (較隨機)
Random r = new Random();

// 2. 固定種子 (可重現序列,利於測試/回放)
Random r = new Random(10010010L);

// 等價於
Random r = new Random(System.currentTimeMillis());

基本生成方法

方法回傳範圍用途
nextInt()int 全範圍 (-2^31 ~ 2^31-1)通用整數、位運算
nextLong()long 全範圍64位隨機、ID 生成
nextBoolean()true/false布林決策
nextFloat()0.0f ~ 1.0f浮點隨機 (CLDC 1.1+)
nextDouble()0.0 ~ 1.0雙精度浮點 (CLDC 1.1+)
nextBytes(byte[])填滿陣列密鑰、鹽值、隨機資料

指定範圍整數生成通用公式

[0, n) 區間 (含 0,不含 n)


int n = 10; // 0-9
int r = Math.abs(random.nextInt() % n);
  • nextInt() 可能為負,Math.abs() 修正為非負。
  • % n 取模縮小範圍。
  • 缺點:Integer.MIN_VALUE 取絕對值仍為負 (溢位),極罕見但理論存在。生產環境建議用 random.nextInt() & 0x7FFFFFFF 保證非負。

[min, max] 閉區間 (含 min 與 max)


int min = 10, max = 20; // 10-20 共 11 個數
int range = max - min + 1; // 11
int r = min + (Math.abs(random.nextInt()) % range);

改良版:無偏差、無溢位風險 (推薦)


public class RandomUtil {
    private static final Random RND = new Random();

    // [0, n)
    public static int nextInt(int n) {
        if (n <= 0) throw new IllegalArgumentException("n must be > 0");
        int bits, val;
        do {
            bits = RND.nextInt() & 0x7FFFFFFF; // 非負
            val = bits % n;
        } while (bits - val + (n - 1) < 0); // 拒絕採樣消除模數偏差
        return val;
    }

    // [min, max]
    public static int nextInt(int min, int max) {
        if (min > max) throw new IllegalArgumentException();
        return min + nextInt(max - min + 1);
    }

    // 隨機布林 (可設定機率)
    public static boolean nextBoolean(float probability) {
        return nextInt(10000) < (probability * 10000);
    }

    // 從陣列隨機取元素
    public static  T randomElement(T[] array) {
        if (array == null || array.length == 0) return null;
        return array[nextInt(array.length)];
    }

    // 洗牌演算法 (Fisher-Yates)
    public static void shuffle(Object[] array) {
        for (int i = array.length - 1; i > 0; i--) {
            int j = nextInt(i + 1);
            Object tmp = array[i];
            array[i] = array[j];
            array[j] = tmp;
        }
    }
}

遊戲實戰應用場景

1. 擲骰子 (1-6)


int dice = RandomUtil.nextInt(1, 6);

2. 隨機生成敵人位置 (螢幕範圍內)


int x = RandomUtil.nextInt(0, getWidth() - enemyWidth);
int y = RandomUtil.nextInt(0, getHeight() - enemyHeight);

3. 掉寶率計算 (10% 機率掉落稀有道具)


if (RandomUtil.nextBoolean(0.10f)) {
    dropRareItem();
}

4. 打亂卡牌/拼圖順序


Card[] deck = createDeck();
RandomUtil.shuffle(deck);

5. 程序化地圖生成種子同步 (多人同步)


// 伺服器發送種子
long seed = System.currentTimeMillis(); // 或協商種子
Random worldGen = new Random(seed);
// 客戶端用相同種子生成相同世界

效能與記憶體建議

  • 單例模式:全域共用一個 Random 實例,避免頻繁建立物件與種子碰撞。
  • 批次生成:nextBytes(byte[]) 一次填滿陣列,比迴圈 nextInt() 快。
  • 避免在 paint() 中生成隨機數:每幀生成會導致畫面閃爍不穩,改在邏輯幀 (update) 生成並緩存。

常見錯誤避雷

  • ❌ Math.abs(random.nextInt()) % n 遇 Integer.MIN_VALUE 產生負數 → 用 & 0x7FFFFFFF 修正。
  • ❌ 模數偏差:n 非 2 的冪次時,餘數分布不均 → 用拒絕採樣 (見改良版)。
  • ❌ 固定種子導致每次遊戲相同 → 正式版用 new Random() 或混合時間+裝置ID作種子。
  • ❌ CLDC 1.0 無 nextFloat/Double → 僅用 nextInt/Long/Boolean/Bytes。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved