Collections.shuffle()源碼分析


Collections.shuffle()源碼分析

  源代碼展示:

 1 public class Collections {  2     private static Random r;  3     private static final int SHUFFLE_THRESHOLD        =    5;  4     
 5     public static void shuffle(List<?> list) {  6         if (r == null) {  7             r = new Random();  8  }  9  shuffle(list, r); 10  } 11     
12     public static void shuffle(List<?> list, Random rnd) { 13         int size = list.size(); 14         if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) { 15             for (int i = size; i > 1; i--) 16                 swap(list, i - 1, rnd.nextInt(i)); 17         } else { 18             Object arr[] = list.toArray(); 19 
20             // Shuffle array
21             for (int i = size; i > 1; i--) 22                 swap(arr, i - 1, rnd.nextInt(i)); 23 
24             // Dump array back into list
25             ListIterator it = list.listIterator(); 26             for (int i = 0; i < arr.length; i++) { 27  it.next(); 28  it.set(arr[i]); 29  } 30  } 31  } 32     
33     public static void swap(List<?> list, int i, int j) { 34         final List l = list; 35  l.set(i, l.set(j, l.get(i))); 36  } 37     
38     private static void swap(Object[] arr, int i, int j) { 39         Object tmp = arr[i]; 40         arr[i] = arr[j]; 41         arr[j] = tmp; 42  } 43     
44 }
 1 public class ArrayList<E> {  2     private transient Object[] elementData;  3     private int size;  4     
 5     public E set(int index, E element) {  6  RangeCheck(index);  7 
 8         E oldValue = (E) elementData[index];  9         elementData[index] = element; 10         return oldValue; 11  } 12     
13     private void RangeCheck(int index) { 14         if (index >= size) 15             throw new IndexOutOfBoundsException("Index: " + index + ", Size: "
16                     + size); 17  } 18 }

 

  經典示例:洗牌算法

 1 import java.util.ArrayList;  2 import java.util.List;  3 import java.util.Random;  4 
 5 public class CollectionsShuffle {  6     public static void main(String[] args) {  7         List<Card> cards = new ArrayList<Card>();  8         // 生成一副牌
 9         for (int rank = Card.THREE; rank <= Card.DEUCE; rank++) {  10             cards.add(new Card(Card.DIAMOND, rank));  11             cards.add(new Card(Card.CLUB, rank));  12             cards.add(new Card(Card.HEART, rank));  13             cards.add(new Card(Card.SPADE, rank));  14  }  15         cards.add(new Card(Card.JOKER, Card.BLACK));  16         cards.add(new Card(Card.JOKER, Card.COLOR));  17  System.out.println(cards.toString());  18         /*
 19  * [方塊3, 梅花3, 紅桃3, 黑桃3, 方塊4, 梅花4, 紅桃4, 黑桃4, 方塊5, 梅花5, 紅桃5, 黑桃5, 方塊6,  20  * 梅花6, 紅桃6, 黑桃6, 方塊7, 梅花7, 紅桃7, 黑桃7, 方塊8, 梅花8, 紅桃8, 黑桃8, 方塊9, 梅花9, 紅桃9,  21  * 黑桃9, 方塊10, 梅花10, 紅桃10, 黑桃10, 方塊J, 梅花J, 紅桃J, 黑桃J, 方塊Q, 梅花Q, 紅桃Q, 黑桃Q,  22  * 方塊K, 梅花K, 紅桃K, 黑桃K, 方塊A, 梅花A, 紅桃A, 黑桃A, 方塊2, 梅花2, 紅桃2, 黑桃2, 小王, 大王]  23          */
 24         // 經典洗牌算法
 25         Random random = new Random();  26         for (int i = cards.size(); i > 1; i--) {  27             int m = random.nextInt(i);  28             swap(cards, i - 1, m);  29  }  30  System.out.println(cards.toString());  31         /*
 32  * [黑桃7, 黑桃A, 梅花A, 紅桃9, 梅花4, 紅桃K, 方塊5, 梅花7, 梅花6, 方塊A, 黑桃Q, 梅花5, 紅桃10,  33  * 梅花Q, 梅花J, 方塊J, 梅花K, 方塊8, 方塊6, 方塊10, 紅桃7, 方塊K, 紅桃6, 黑桃2, 黑桃K, 梅花10,  34  * 紅桃8, 方塊Q, 紅桃Q, 大王, 梅花3, 梅花2, 方塊7, 方塊9, 方塊4, 紅桃3, 梅花9, 紅桃J, 黑桃8, 紅桃2,  35  * 黑桃6, 紅桃A, 黑桃9, 黑桃4, 黑桃J, 黑桃10, 小王, 黑桃3, 黑桃5, 紅桃5, 紅桃4, 方塊2, 方塊3, 梅花8]  36          */
 37 
 38  }  39 
 40     public static void swap(List<?> list, int i, int j) {  41         final List l = list;  42  l.set(i, l.set(j, l.get(i)));  43  }  44 }  45 
 46 class Card {  47 
 48     public static final int DIAMOND = 0; // 方塊(鑽石)
 49     public final static int CLUB = 1; // 梅花
 50     public static final int HEART = 2; // 紅桃(紅心)
 51     public static final int SPADE = 3; // 黑桃(花鋤)
 52     public static final int JOKER = 4; //
 53 
 54     public final static int THREE = 0;  55     public final static int FOUR = 1;  56     public final static int FIVE = 2;  57     public final static int SIX = 3;  58     public final static int SEVEN = 4;  59     public final static int EIGHT = 5;  60     public final static int NINE = 6;  61     public final static int TEN = 7;  62     public final static int JACK = 8;// J
 63     public final static int QUEEN = 9;// Q
 64     public final static int KING = 10;// K
 65     public final static int ACE = 11;// A
 66     public final static int DEUCE = 12; // 2
 67     public final static int BLACK = 13; // 小王
 68     public final static int COLOR = 14;// 大王
 69 
 70     /** 花色 0代表方塊, 1代表梅花, 2代表紅桃, 3代表黑桃,4:王 */
 71     private int suit;  72     /** 點數 規定: 0代表3, 1代表4, 2代表5,... */
 73     private int rank;  74 
 75     public Card() {  76  }  77 
 78     public Card(int suit, int rank) {  79         // this.rank = rank;  80         // this.suit = suit;
 81  setRank(rank);  82  setSuit(suit);  83  }  84 
 85     public int getSuit() {  86         return suit;  87  }  88 
 89     public void setSuit(int suit) {  90         if (suit < DIAMOND || suit > JOKER)  91             throw new RuntimeException("花色超過范圍!");  92         this.suit = suit;  93  }  94 
 95     public int getRank() {  96         return rank;  97  }  98 
 99     public void setRank(int rank) { 100         if (rank < THREE || rank > COLOR) { 101             throw new RuntimeException("點數超過范圍!"); 102  } 103         this.rank = rank; 104  } 105 
106     private static final String[] RANK_NAMES = { "3", "4", "5", "6", "7", "8", 107             "9", "10", "J", "Q", "K", "A", "2", "小王", "大王" }; 108     private static final String[] SUIT_NAMES = { "方塊", "梅花", "紅桃", "黑桃", "" }; 109 
110     // 覆蓋Object 類的toStirng() 方法. 實現對象的文本描述
111     public String toString() { 112         return SUIT_NAMES[suit] + RANK_NAMES[rank]; 113  } 114 
115     public boolean equals(Object obj) { 116         if (obj == null) { 117             return false; 118  } 119         if (this == obj) { 120             return true; 121  } 122         if (obj instanceof Card) { 123             Card other = (Card) obj; 124             return this.rank == other.rank && this.suit == other.suit; 125  } 126         return false; 127  } 128 
129     public int hashCode() { 130         // return suit*100+rank; 131         // suit=3= 00000000 00000000 00000000 00000011 132         // rank=10=00000000 00000000 00000000 00000011 133         // suit<<16=00000000 00000011 00000000 00000000 134         // 00000000 00000011 00000000 00000011
135         return (suit << 16) + rank;// (x<<16)+y
136  } 137 }

 

 

 

 

 

 

 

 

 


免責聲明!

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



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