首页 » 编写高质量代码:改善Java程序的151个建议 » 编写高质量代码:改善Java程序的151个建议全文在线阅读

《编写高质量代码:改善Java程序的151个建议》建议77:使用shuffle打乱列表

关灯直达底部

在网站上我们经常会看到关键字云(Word Cloud)和标签云(Tag Cloud),用于表明这个关键字或标签是经常被查阅的,而且还可以看到这些标签的动态运动,每次刷新都会有不一样的关键字或标签,让浏览者觉得这个网站的访问量非常大,短短的几分钟就有这么多的搜索量。不过,这在Java中该如何实现呢?代码如下:


public static void main(Stringargs){

int tagCloudNum=10;

List<String>tagClouds=new ArrayList<String>(tagCloudNum);

//初始化标签云,一般是从数据库读入,省略

Random rand=new Random();

for(int i=0;i<tagCloudNum;i++){

//取得随机位置

int randomPosition=rand.nextInt(tagCloudNum);

//当前元素与随机元素交换

String temp=tagClouds.get(i);

tagClouds.set(i, tagClouds.get(randomPosition));

tagClouds.set(randomPosition, temp);

}

}


先从数据库中读出标签,然后使用随机数打乱,每次都产生不同的顺序,恩,确实能让浏览者感觉到我们的标签云顺序在变化——浏览者多嘛!但是,对于乱序处理我们可以有更好的实现方式,先来修改第一版:


public static void main(Stringargs){

int tagCloudNum=10;

List<String>tagClouds=new ArrayList<String>(tagCloudNum);

Random rand=new Random();

for(int i=0;i<tagCloudNum;i++){

//取得随机位置

int randomPosition=rand.nextInt(tagCloudNum);

//当前元素与随机元素交换

Collections.swap(tagClouds, i,randomPosition);

}

}


上面使用了Collections的swap方法,该方法会交换两个位置的元素值,不用我们自己写交换代码了。难道乱序到此就优化完了吗?没有,我们可以继续重构,第二版重构如下:


public static void main(Stringargs){

int tagCloudNum=10;

List<String>tagClouds=new ArrayList<String>(tagCloudNum);

//打乱顺序

Collections.shuffe(tagClouds);

}


这才是我们想要的结果,就这一句话,即可打乱一个列表的顺序,不用我们费尽心思的遍历、替换元素了。我们一般很少用到shuffle这个方法,那它可以用在什么地方呢?

可以用在程序的“伪装”上。

比如我们例子中的标签云,或者是游戏中的打怪、修行、群殴时宝物的分配策略。

可以用在抽奖程序中。

比如年会的抽奖程序,先使用shuffle把员工排序打乱,每个员工的中奖几率就是相等的了,然后就可以抽取第一名、第二名。

可以用在安全传输方面。

比如发送端发送一组数据,先随机打乱顺序,然后加密发送,接收端解密,然后自行排序,即可实现即使是相同的数据源,也会产生不同密文的效果,加强了数据的安全性。