java.lang.Math 與 java.util.Random 是 Java 基礎開發中最高頻的工具類,掌握其核心方法能顯著提升編碼效率與代碼質量。
提供科學計算常用函數,所有方法均為 static,直接 Math.xxx() 調用。
Math.PI:π ≈ 3.141592653589793Math.E:自然對數底數 e ≈ 2.718281828459045| 方法簽名 | 功能 | 示例/備註 |
|---|---|---|
abs(int/long/float/double) | 絕對值 | Math.abs(-5) == 5;注意 Integer.MIN_VALUE 絕對值仍為負(溢出) |
ceil(double) | 向上取整(≥參數的最小整數) | Math.ceil(3.2) == 4.0;返回 double |
floor(double) | 向下取整(≤參數的最大整數) | Math.floor(3.8) == 3.0;返回 double |
round(float/double) | 四捨五入到最接近的整數 | Math.round(3.5) == 4;float→int,double→long |
max/min(int/long/float/double) | 最大/最小值 | Math.max(3, 5) == 5 |
sqrt(double) | 平方根 | Math.sqrt(9) == 3.0;參數 < 0 返回 NaN |
pow(double, double) | 冪運算 ab | Math.pow(2, 10) == 1024.0 |
random() | 返回 [0.0, 1.0) 偽隨機 double | 等價 new Random().nextDouble();線程安全但爭用較大 |
sin/cos/tan/asin/acos/atan | 三角函數 | 參數/返回值均為弧度;toRadians()/toDegrees() 轉換 |
log/log10/log1p | 自然對數/常用對數/ln(x+1) | Math.log(Math.E) == 1.0 |
exp/expm1 | ex / ex-1 | 小數值時 expm1 精度更高 |
hypot(x, y) | √(x²+y²) 無溢出風險 | 計算向量模長首選 |
cbrt(x) | 立方根 | 負數也能正確計算 |
signum(x) | 符號函數:-1/0/1 | 判斷正負零利器 |
ulp(x) | 單位在最後一位(精度分析) | 浮點數誤差分析專用 |
// 1. 保留 n 位小數(四捨五入)
double rounded = Math.round(value * Math.pow(10, n)) / Math.pow(10, n);
// 2. 區間隨機整數 [min, max]
int randomInt = (int)(Math.random() * (max - min + 1)) + min;
// 3. 安全的整數中點計算(避免溢出)
int mid = (low + high) >>> 1; // 或 Math.addExact(low, high) / 2
// 4. 判斷 2 的冪次
boolean isPowerOfTwo = (n > 0) && ((n & (n - 1)) == 0);
基於線性同餘算法(LCG),非線程安全,高併發下推薦 ThreadLocalRandom(JDK 7+)或 SplittableRandom(JDK 8+)。
new Random():種子 = System.nanoTime() + 計數器new Random(long seed):固定種子,可復現序列(測試/調試專用)| 方法 | 返回範圍/類型 | 說明 |
|---|---|---|
nextInt() | int 全範圍 | 含負數 |
nextInt(int bound) | [0, bound) int | bound > 0,均勻分佈 |
nextLong() | long 全範圍 | 含負數 |
nextFloat() | [0.0, 1.0) float | |
nextDouble() | [0.0, 1.0) double | |
nextBoolean() | true/false | 均勻分佈 |
nextGaussian() | double | 標準正態分佈 μ=0, σ=1 |
nextBytes(byte[]) | void | 填充字節數組,生成隨機 Token/鹽值 |
// 1. 區間隨機長整數 [min, max]
long randomLong = min + random.nextLong(max - min + 1); // JDK 17+ nextLong(bound)
// 2. 加權隨機 / 概率選擇
int weightedChoice(double[] probabilities) {
double r = random.nextDouble();
double sum = 0;
for (int i = 0; i < probabilities.length; i++) {
sum += probabilities[i];
if (r < sum) return i;
}
return probabilities.length - 1;
}
// 3. 打亂數組(Fisher-Yates 洗牌)
void shuffle(int[] arr) {
for (int i = arr.length - 1; i > 0; i--) {
int j = random.nextInt(i + 1);
int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp;
}
}
// 4. 線程安全替代:ThreadLocalRandom.current().nextInt(bound)
| 場景 | 推薦類 | 理由 |
|---|---|---|
| 簡單單線程/學習 | Math.random() / new Random() | API 簡單,無依賴 |
| 高併發業務 | ThreadLocalRandom | 無鎖、ThreadLocal 隔離、性能最優 |
| 並行流/分治任務 | SplittableRandom | 可分裂、統計質量更好 |
| 加密/安全敏感 | SecureRandom | 密碼學強度、熵源、速度較慢 |
| 可復現測試 | new Random(fixedSeed) | 決定性序列,便於回歸測試 |
熟練掌握 Math 與 Random 的核心方法、邊界行為及性能特徵,能讓日常數值計算、隨機邏輯、演算法實現更加精準、高效、健壯。