shuffle洗牌算法java_Collections.shuffle()源码分析

Collections.shuffle()源码分析

源代码展示:

public class Collections {

private static Random r;

private static final int SHUFFLE_THRESHOLD = 5;

public static void shuffle(List> list) {

if (r == null) {

r = new Random();

}

shuffle(list, r);

}

public static void shuffle(List> list, Random rnd) {

int size = list.size();

if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {

for (int i = size; i > 1; i--)

swap(list, i - 1, rnd.nextInt(i));

} else {

Object arr[] = list.toArray();

// Shuffle array

for (int i = size; i > 1; i--)

swap(arr, i - 1, rnd.nextInt(i));

// Dump array back into list

ListIterator it = list.listIterator();

for (int i = 0; i < arr.length; i++) {

it.next();

it.set(arr[i]);

}

}

}

public static void swap(List> list, int i, int j) {

final List l = list;

l.set(i, l.set(j, l.get(i)));

}

private static void swap(Object[] arr, int i, int j) {

Object tmp = arr[i];

arr[i] = arr[j];

arr[j] = tmp;

}

}

public class ArrayList {

private transient Object[] elementData;

private int size;

public E set(int index, E element) {

RangeCheck(index);

E oldValue = (E) elementData[index];

elementData[index] = element;

return oldValue;

}

private void RangeCheck(int index) {

if (index >= size)

throw new IndexOutOfBoundsException("Index: " + index + ", Size: "

+ size);

}

}

经典示例:洗牌算法

import java.util.ArrayList;

import java.util.List;

import java.util.Random;

public class CollectionsShuffle {

public static void main(String[] args) {

List cards = new ArrayList();

// 生成一副牌

for (int rank = Card.THREE; rank <= Card.DEUCE; rank++) {

cards.add(new Card(Card.DIAMOND, rank));

cards.add(new Card(Card.CLUB, rank));

cards.add(new Card(Card.HEART, rank));

cards.add(new Card(Card.SPADE, rank));

}

cards.add(new Card(Card.JOKER, Card.BLACK));

cards.add(new Card(Card.JOKER, Card.COLOR));

System.out.println(cards.toString());

/*

* [方块3, 梅花3, 红桃3, 黑桃3, 方块4, 梅花4, 红桃4, 黑桃4, 方块5, 梅花5, 红桃5, 黑桃5, 方块6,

* 梅花6, 红桃6, 黑桃6, 方块7, 梅花7, 红桃7, 黑桃7, 方块8, 梅花8, 红桃8, 黑桃8, 方块9, 梅花9, 红桃9,

* 黑桃9, 方块10, 梅花10, 红桃10, 黑桃10, 方块J, 梅花J, 红桃J, 黑桃J, 方块Q, 梅花Q, 红桃Q, 黑桃Q,

* 方块K, 梅花K, 红桃K, 黑桃K, 方块A, 梅花A, 红桃A, 黑桃A, 方块2, 梅花2, 红桃2, 黑桃2, 小王, 大王]

*/

// 经典洗牌算法

Random random = new Random();

for (int i = cards.size(); i > 1; i--) {

int m = random.nextInt(i);

swap(cards, i - 1, m);

}

System.out.println(cards.toString());

/*

* [黑桃7, 黑桃A, 梅花A, 红桃9, 梅花4, 红桃K, 方块5, 梅花7, 梅花6, 方块A, 黑桃Q, 梅花5, 红桃10,

* 梅花Q, 梅花J, 方块J, 梅花K, 方块8, 方块6, 方块10, 红桃7, 方块K, 红桃6, 黑桃2, 黑桃K, 梅花10,

* 红桃8, 方块Q, 红桃Q, 大王, 梅花3, 梅花2, 方块7, 方块9, 方块4, 红桃3, 梅花9, 红桃J, 黑桃8, 红桃2,

* 黑桃6, 红桃A, 黑桃9, 黑桃4, 黑桃J, 黑桃10, 小王, 黑桃3, 黑桃5, 红桃5, 红桃4, 方块2, 方块3, 梅花8]

*/

}

public static void swap(List> list, int i, int j) {

final List l = list;

l.set(i, l.set(j, l.get(i)));

}

}

class Card {

public static final int DIAMOND = 0; // 方块(钻石)

public final static int CLUB = 1; // 梅花

public static final int HEART = 2; // 红桃(红心)

public static final int SPADE = 3; // 黑桃(花锄)

public static final int JOKER = 4; // 王

public final static int THREE = 0;

public final static int FOUR = 1;

public final static int FIVE = 2;

public final static int SIX = 3;

public final static int SEVEN = 4;

public final static int EIGHT = 5;

public final static int NINE = 6;

public final static int TEN = 7;

public final static int JACK = 8;// J

public final static int QUEEN = 9;// Q

public final static int KING = 10;// K

public final static int ACE = 11;// A

public final static int DEUCE = 12; // 2

public final static int BLACK = 13; // 小王

public final static int COLOR = 14;// 大王

/** 花色 0代表方块, 1代表梅花, 2代表红桃, 3代表黑桃,4:王 */

private int suit;

/** 点数 规定: 0代表3, 1代表4, 2代表5,... */

private int rank;

public Card() {

}

public Card(int suit, int rank) {

// this.rank = rank;

// this.suit = suit;

setRank(rank);

setSuit(suit);

}

public int getSuit() {

return suit;

}

public void setSuit(int suit) {

if (suit < DIAMOND || suit > JOKER)

throw new RuntimeException("花色超过范围!");

this.suit = suit;

}

public int getRank() {

return rank;

}

public void setRank(int rank) {

if (rank < THREE || rank > COLOR) {

throw new RuntimeException("点数超过范围!");

}

this.rank = rank;

}

private static final String[] RANK_NAMES = { "3", "4", "5", "6", "7", "8",

"9", "10", "J", "Q", "K", "A", "2", "小王", "大王" };

private static final String[] SUIT_NAMES = { "方块", "梅花", "红桃", "黑桃", "" };

// 覆盖Object 类的toStirng() 方法. 实现对象的文本描述

public String toString() {

return SUIT_NAMES[suit] + RANK_NAMES[rank];

}

public boolean equals(Object obj) {

if (obj == null) {

return false;

}

if (this == obj) {

return true;

}

if (obj instanceof Card) {

Card other = (Card) obj;

return this.rank == other.rank && this.suit == other.suit;

}

return false;

}

public int hashCode() {

// return suit*100+rank;

// suit=3= 00000000 00000000 00000000 00000011

// rank=10=00000000 00000000 00000000 00000011

// suit<<16=00000000 00000011 00000000 00000000

// 00000000 00000011 00000000 00000011

return (suit << 16) + rank;// (x<<16)+y

}

}

https://www.cnblogs.com/gw811/category/386555.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值