在网站上我们经常会看到关键字云(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);
}
这才是我们想要的结果,就这一句话即可打乱一个列表的顺序,不用我们费尽心思的遍历、替换元素了!
现在来测试一下,是不是都能成功实现打乱顺序呢?下面给出完整源代码:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random; /**
* 打乱列表中数据元素的三种实现方法
*/
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);
} }
输出结果如下:
aaarticlea/png;base64,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" alt="" />
我们一般很少用到shuffle这个方法,那它可以用在什么地方呢?
(1)可以用在程序的“伪装”上
比如我们例子中的标签云,或者是游戏中的打怪、修行、群殴时宝物的分配策略。 (2)可以用在抽奖程序中
比如年会的抽奖程序,先使用shuffle把员工顺序打乱,每个员工的中奖几率就是相等的了,然后就可以抽取第一名、第二名。 (3)可以用在安全传输方面
比如发送端发送一组数据,先随机打乱顺序,然后加密发送,接收端解密,然后自行排序,即可实现即使是相同的数据源,也会产生不同密文的效果,加强了数据的安全性。
http://www.cnblogs.com/lanxuezaipiao/p/3192980.html
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.util.StopWatch; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; /**
* @author: tangcheng
* @description:
* @since: Created in 2018/08/07 11:01
*/
@Slf4j
public class CollectShuttleTest { /**
* 从1000个中去掉100个,总耗时18ms
* 混淆后的数据,没有发现明显的问题
*/
@Test
public void shuffleTest() {
List<Integer> total = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
total.add(i);
}
StopWatch stopWatch = new StopWatch("Collections.shuffle()");
int count = 100;
List<Integer> winnerList = new ArrayList<>(100);
for (int i = 0; i < count; i++) {
stopWatch.start("time_" + i);
Collections.shuffle(total);
int index = total.size() - 1;
Integer winner = total.remove(index);
winnerList.add(winner);
log.info("taskName:{},winner:{}", i, winner);
stopWatch.stop();
}
log.info("winnerList:{},stopWatch.prettyPrint():{}", winnerList, stopWatch.prettyPrint());
/**
* winnerList:[
* 163, 905, 954, 828, 387, 217, 272, 662, 753, 160,
* 636, 629, 132, 318, 655, 388, 501, 879, 625, 515,
* 339, 897, 497, 959, 819, 654, 71, 984, 356, 256,
* 539, 330, 888, 643, 928, 10, 213, 878, 935, 206,
* 53, 875, 437, 422, 997, 464, 276, 65, 451, 732,
* 432, 154, 385, 955, 161, 719, 352, 383, 37, 853,
* 675, 696, 646, 223, 742, 807, 76, 738, 415, 516,
* 890, 656, 610, 910, 80, 7, 561, 548, 947, 390,
* 949, 236, 382, 338, 112, 240, 162, 642, 754, 571,
* 8, 802, 532, 410, 372, 462, 880, 38, 744, 360
* ],
* stopWatch.prettyPrint():StopWatch 'Collections.shuffle()': running time (millis) = 18
* -----------------------------------------
* ms % Task name
* -----------------------------------------
* 00007 039% time_0
* 00000 000% time_1
* 00000 000% time_2
* 00001 006% time_3
* 00000 000% time_4
* 00000 000% time_5
* 00000 000% time_6
* 00000 000% time_7
* 00000 000% time_8
* 00000 000% time_9
* 00000 000% time_10
* 00000 000% time_11
* 00001 006% time_12
* 00000 000% time_13
* 00000 000% time_14
* 00000 000% time_15
* 00000 000% time_16
* 00000 000% time_17
* 00000 000% time_18
* 00000 000% time_19
* 00000 000% time_20
* 00000 000% time_21
* 00000 000% time_22
* 00000 000% time_23
* 00001 006% time_24
* 00000 000% time_25
* 00000 000% time_26
* 00000 000% time_27
* 00001 006% time_28
* 00000 000% time_29
* 00001 006% time_30
* 00000 000% time_31
* 00000 000% time_32
* 00000 000% time_33
* 00000 000% time_34
* 00000 000% time_35
* 00000 000% time_36
* 00000 000% time_37
* 00000 000% time_38
* 00000 000% time_39
* 00000 000% time_40
* 00001 006% time_41
* 00000 000% time_42
* 00000 000% time_43
* 00000 000% time_44
* 00000 000% time_45
* 00000 000% time_46
* 00000 000% time_47
* 00000 000% time_48
* 00000 000% time_49
* 00000 000% time_50
* 00001 006% time_51
* 00000 000% time_52
* 00000 000% time_53
* 00000 000% time_54
* 00000 000% time_55
* 00000 000% time_56
* 00000 000% time_57
* 00000 000% time_58
* 00000 000% time_59
* 00000 000% time_60
* 00000 000% time_61
* 00000 000% time_62
* 00001 006% time_63
* 00000 000% time_64
* 00000 000% time_65
* 00001 006% time_66
* 00000 000% time_67
* 00000 000% time_68
* 00000 000% time_69
* 00000 000% time_70
* 00000 000% time_71
* 00000 000% time_72
* 00000 000% time_73
* 00000 000% time_74
* 00000 000% time_75
* 00000 000% time_76
* 00001 006% time_77
* 00000 000% time_78
* 00000 000% time_79
* 00000 000% time_80
* 00000 000% time_81
* 00000 000% time_82
* 00000 000% time_83
* 00000 000% time_84
* 00000 000% time_85
* 00000 000% time_86
* 00000 000% time_87
* 00000 000% time_88
* 00000 000% time_89
* 00000 000% time_90
* 00000 000% time_91
* 00001 006% time_92
* 00000 000% time_93
* 00000 000% time_94
* 00000 000% time_95
* 00000 000% time_96
* 00000 000% time_97
* 00000 000% time_98
* 00000 000% time_99
*/
} }