Collections類中的shuffle方法源碼分析
shuffle方法可以將List中的數(shù)據(jù)隨機打亂順序,之前我們就使用了這個方法實現(xiàn)了撲克牌的洗牌功能,下面來看下shuffle方法的源碼:

該方法中獲取了一個隨機數(shù)的對象,之后調用了與其構成重載的另一個shuffle方法:

上面的shuffle方法有個邏輯判斷,第一個判斷是當List對象的長度小于5或者List對象是RandomAccess實例的時候直接執(zhí)行了for循環(huán),在這個for循環(huán)中調用了swap方法:

在這個swap方法中可以看到,
swap方法中接收的參數(shù)j是一個隨機數(shù),將這個隨機數(shù)j作為索引位置,直接調用了list中的set方法來修改list中的數(shù)據(jù)。這個其實就相當于是使用了基本的for循環(huán)和隨機數(shù)來實現(xiàn)的隨機打亂list中的數(shù)據(jù)順序。
再回到shuffle方法,在邏輯判斷中還有一個else,在這個里面的做法是先將list轉換為數(shù)組,之后使用for循環(huán)和隨機數(shù)來隨機打亂該數(shù)組的順序,最后使用了迭代器來將這個數(shù)組中的數(shù)據(jù)放入到list中,這樣就相對于隨機的改變了list中的數(shù)據(jù)順序。

以上就是shuffle方法的源碼簡要分析。這里有一個問題,就是為什么在shuffle方法中要有一個邏輯判斷呢?直接修改list中數(shù)據(jù)的順序不就行了嗎。這個就跟list有關系了,List只是一個接口,有一些他的實現(xiàn)類,最具代表性的是ArrayList和LinkedList。
當調用shuffle方法時傳入的是ArrayList的話,因為ArrayList實現(xiàn)了RandomAccess接口,那么就會執(zhí)行if中的代碼,這里面的做法是使用一個基本for循環(huán)直接修改list中的數(shù)據(jù)。
當調用shuffle方法時傳入的是LinkedList的話,就會執(zhí)行else中的代碼,他在里面先將其轉換為數(shù)組,然后再將數(shù)組中的元素使用迭代器再重新放入到LinkedList中。
在使用基本for循環(huán)對ArrayList和LinkedList進行遍歷的時候,ArrayList的運行效率要遠比LinkedList高,這是因為ArrayList底層使用數(shù)組實現(xiàn),所以通過下標訪問的話ArrayList效率高。
當時用迭代器或者增強for循環(huán)(底層就是使用的迭代器)遍歷ArrayList和LinkedList時,因為LinkedList底層使用鏈表實現(xiàn),所以LinkedList的效率遠比ArrayList高。
由于以上的原因,為了程序的效率,所以在shuffle方法中使用了邏輯判斷來區(qū)分具體是哪一種List從而高效的對其進行遍歷。