• 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 }
  • 相关阅读:
    博客园CSS备份5
    博客园界面自定义教程
    awk 入门教程(阮一峰)
    批量检查cksum是否一致
    linux文件批量重命名
    cipher block
    riscv-gdbserver
    rsa_gmp
    asic
    video
  • 原文地址:https://www.cnblogs.com/gw811/p/2719134.html
Copyright © 2020-2023  润新知