你會用shuffle打亂列表嗎?


     在網站上我們經常會看到關鍵字雲(Word Cloud)和標簽雲(Tag Cloud),用於表明這個關鍵字或標簽是經常被查閱的,而且還可以看到這些標簽的動態運動,每次刷新都會有不一樣的關鍵字或便簽,讓瀏覽者覺得這個網站的訪問量非常大,短短的幾分鍾就有這么多的搜索量。這是怎么實現的呢?其實非常簡單:先從數據庫中讀出標簽,然后使用隨機數打亂,每次都產生不同的順序,嗯,確實能讓瀏覽者感覺到我們的標簽雲順序在變——瀏覽者多嘛!但是,對於亂序處理我們有哪些方法呢?

下面給出一個大家都會想到的方法:

    public <T> void shuffle1(List<T> list) {
        int size = list.size();
        Random random = new Random();
        
        for(int i = 0; i < size; i++) {
            // 獲取隨機位置
            int randomPos = random.nextInt(size);
            
            // 當前元素與隨機元素交換
            T temp = list.get(i);
            list.set(i, list.get(randomPos));
            list.set(randomPos, temp);
        }
    }

很簡單,實現方法也很多,但有更簡單的實現方法:

    public <T> void shuffle2(List<T> list) {
        int size = list.size();
        Random random = new Random();
        
        for(int i = 0; i < size; i++) {
            // 獲取隨機位置
            int randomPos = random.nextInt(size);
            
            // 當前元素與隨機元素交換
            Collections.swap(list, i, randomPos);
        }
    }

上面使用了Collections的swap方法,該方法會交換兩個位置的元素值,不用我們自己寫交換代碼了,是不是更簡單呢?

其實,我想說,還有更更簡單的方法,如下:

    public <T> void shuffle3(List<T> list) {
        // 打亂順序
        Collections.shuffle(list);
    }

這才是我們想要的結果,就這一句話即可打亂一個列表的順序,不用我們費盡心思的遍歷、替換元素了!

現在來測試一下,是不是都能成功實現打亂順序呢?下面給出完整源代碼:

package arrlist;

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

/**
 * 打亂列表中數據元素的三種實現方法
 * 
 * @author Alexia
 * @date 2013-7-16
 *
 */
public class ShuffleTest {

    // 打亂列表實現方法1
    public <T> void shuffle1(List<T> list) {
        int size = list.size();
        Random random = new Random();
        
        for(int i = 0; i < size; i++) {
            // 獲取隨機位置
            int randomPos = random.nextInt(size);
            
            // 當前元素與隨機元素交換
            T temp = list.get(i);
            list.set(i, list.get(randomPos));
            list.set(randomPos, temp);
        }
    }
    
    // 打亂列表實現方法2
    public <T> void shuffle2(List<T> list) {
        int size = list.size();
        Random random = new Random();
        
        for(int i = 0; i < size; i++) {
            // 獲取隨機位置
            int randomPos = random.nextInt(size);
            
            // 當前元素與隨機元素交換
            Collections.swap(list, i, randomPos);
        }
    }
    
    // 打亂列表實現方法3
    public <T> void shuffle3(List<T> list) {
        // 打亂順序
        Collections.shuffle(list);
    }
    
    // 打印列表
    public <T> void print(List<T> list) {
        for(T t : list) {
            System.out.print(t + " ");
        }
        
        System.out.println("\n");
    }
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        ShuffleTest st = new ShuffleTest();
        List<String> tagClouds = new ArrayList<String>(6);
        
        // 一般從數據庫中讀取,這里僅以測試為目的
        tagClouds.add("計算機");
        tagClouds.add("Java");
        tagClouds.add("編程");
        tagClouds.add("C/C++");
        tagClouds.add("操作系統");
        tagClouds.add("數據庫");
        System.out.println("原順序:");
        st.print(tagClouds);
        
        st.shuffle1(tagClouds);
        System.out.println("打亂順序一:");
        st.print(tagClouds);
        
        st.shuffle2(tagClouds);
        System.out.println("打亂順序二:");
        st.print(tagClouds);
        
        st.shuffle3(tagClouds);
        System.out.println("打亂順序三:");
        st.print(tagClouds);
    }

}

輸出結果如下:

我們一般很少用到shuffle這個方法,那它可以用在什么地方呢?

(1)可以用在程序的“偽裝”上

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

(2)可以用在抽獎程序中

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

(3)可以用在安全傳輸方面

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM