讀古今文學網 > 編寫高質量代碼:改善Java程序的151個建議 > 建議77:使用shuffle打亂列表 >

建議77:使用shuffle打亂列表

在網站上我們經常會看到關鍵字雲(Word Cloud)和標籤雲(Tag Cloud),用於表明這個關鍵字或標籤是經常被查閱的,而且還可以看到這些標籤的動態運動,每次刷新都會有不一樣的關鍵字或標籤,讓瀏覽者覺得這個網站的訪問量非常大,短短的幾分鐘就有這麼多的搜索量。不過,這在Java中該如何實現呢?代碼如下:


public static void main(Stringargs){

int tagCloudNum=10;

List<String>tagClouds=new ArrayList<String>(tagCloudNum);

//初始化標籤雲,一般是從數據庫讀入,省略

Random rand=new Random();

for(int i=0;i<tagCloudNum;i++){

//取得隨機位置

int randomPosition=rand.nextInt(tagCloudNum);

//當前元素與隨機元素交換

String temp=tagClouds.get(i);

tagClouds.set(i, tagClouds.get(randomPosition));

tagClouds.set(randomPosition, temp);

}

}


先從數據庫中讀出標籤,然後使用隨機數打亂,每次都產生不同的順序,嗯,確實能讓瀏覽者感覺到我們的標籤雲順序在變化——瀏覽者多嘛!但是,對於亂序處理我們可以有更好的實現方式,先來修改第一版:


public static void main(Stringargs){

int tagCloudNum=10;

List<String>tagClouds=new ArrayList<String>(tagCloudNum);

Random rand=new Random();

for(int i=0;i<tagCloudNum;i++){

//取得隨機位置

int randomPosition=rand.nextInt(tagCloudNum);

//當前元素與隨機元素交換

Collections.swap(tagClouds, i,randomPosition);

}

}


上面使用了Collections的swap方法,該方法會交換兩個位置的元素值,不用我們自己寫交換代碼了。難道亂序到此就優化完了嗎?沒有,我們可以繼續重構,第二版重構如下:


public static void main(Stringargs){

int tagCloudNum=10;

List<String>tagClouds=new ArrayList<String>(tagCloudNum);

//打亂順序

Collections.shuffe(tagClouds);

}


這才是我們想要的結果,就這一句話,即可打亂一個列表的順序,不用我們費盡心思的遍歷、替換元素了。我們一般很少用到shuffle這個方法,那它可以用在什麼地方呢?

可以用在程序的「偽裝」上。

比如我們例子中的標籤雲,或者是遊戲中的打怪、修行、群毆時寶物的分配策略。

可以用在抽獎程序中。

比如年會的抽獎程序,先使用shuffle把員工排序打亂,每個員工的中獎幾率就是相等的了,然後就可以抽取第一名、第二名。

可以用在安全傳輸方面。

比如發送端發送一組數據,先隨機打亂順序,然後加密發送,接收端解密,然後自行排序,即可實現即使是相同的數據源,也會產生不同密文的效果,加強了數據的安全性。