1. 程式人生 > >記一次JAVA中的Random使用經驗

記一次JAVA中的Random使用經驗

專案中遇到這樣一個需求,在資訊流中拉取其他源的新聞,每次大概會拉取到10條,其中有些是沒有標題或者標題不符合規範的,需要對這種的標題進行識別並替換,隨機替換為預先設定的大概5個預設標題中的一個。需求簡單,核心在於隨機選取,一下就想到了Random類,遍歷每次的10條新聞,判斷為需要替換標題時用Random隨機索引,從5個預設標題中隨機選取標題替換,起初程式碼邏輯大概如下。

import java.util.Arrays;
import java.util.Random;

public class TestRandom {

    private static String[] titles = {"1-title","2-title","3-title","4-title","5-title"};
    private static String[] news = new String[10];

    public static void main(String[] args) {
        for(int i = 0; i < 10; i++){
            Random random = new Random(System.currentTimeMillis());
            int index = random.nextInt(titles.length);
            news[i] = titles[index];
        }
        System.out.println(Arrays.toString(news));
    }
}

一切都感覺挺好,但是發現每次拉取到的新聞被替換後都是選用同一個預設標題,上述程式碼的一次執行結果為[2-title, 2-title, 2-title, 2-title, 2-title, 2-title, 2-title, 2-title, 2-title, 2-title],問題出在哪裡呢。唯一的可能就是每次都隨機到了同一個索引,通過加一些Log發現迴圈過程中,每回System.currentTimeMillis()返回的時間戳是完全相同的,該函式返回的是毫秒,對於計算機來說,1ms能幹的事太多了,一個for迴圈用的時間還不到1ms,這就導致了Random的種子是相同的,Random每次返回的隨機序列也就會相同,從而導致選中同一個標題。

解決方法也很簡單,那就是避免Random種子相同,可以把Random random = new Random(System.currentTimeMillis());這句從迴圈中提取出去,修改後程式碼如下。

import java.util.Arrays;
import java.util.Random;

public class TestRandom {

    private static String[] titles = {"1-title","2-title","3-title","4-title","5-title"};
    private static String[] news = new String[10];
    privat static Random random = new Random();

    public static void main(String[] args) {
        for(int i = 0; i < 10; i++){
            int index = random.nextInt(titles.length);
            news[i] = titles[index];
        }
        System.out.println(Arrays.toString(news));
    }

如此便解決了問題。可以看到,這次隨機時乾脆就沒有用到種子了。種子其實就是為了保證每次隨機出來的隨機數序列是不同的,而在上述的需求中不需要設定種子。

其實這是一個很簡單的問題,寫此博就是為了記錄一下自己的一次踩坑經歷,當然如果能給新手一些啟發就更好了。