想到要生成隨機(jī)數(shù)莉擒,第一個(gè)當(dāng)然想到的是Random這個(gè)Java提供的類澜躺,使用random.nextInt
可以很方便的得到一個(gè)隨機(jī)數(shù)吼虎,使用random.nextInt(100)
可以得到一個(gè)0-100之間的隨機(jī)數(shù)元暴,然后使用List來存放隨機(jī)數(shù)喜颁,內(nèi)部使用for循環(huán)來確保值的唯一性稠氮,代碼如下:
//輸入number=999;
long s1 = System.currentTimeMillis(); // 開始測試時(shí)間
Random r1 = new Random();
List<Integer> l1 = new ArrayList<>();
int a = 0;
while (l1.size() < number) {
int index = r1.nextInt();
if (!l1.contains(index)) {
l1.add(index);
}
a++;
}
long e1 = System.currentTimeMillis(); // 獲取結(jié)束時(shí)間
System.out.println("耗時(shí) = " + (e1 - s1) + ",數(shù)據(jù)容量 = " + l1.size()
+ ",執(zhí)行次數(shù) = " + a);
結(jié)果:耗時(shí) = 5,數(shù)據(jù)容量 = 999,執(zhí)行次數(shù) = 999;
好像沒啥問題喔,耗時(shí)5好秒半开,很快喔隔披,那我們改一下代碼,把r1.nextInt();
改成r1.nextInt(1000);
1000個(gè)數(shù)找999個(gè)不一樣的寂拆,效果如下
結(jié)果:耗時(shí) = 10,數(shù)據(jù)容量 = 999,執(zhí)行次數(shù) = 6321
好像也沒啥問題奢米,那么,改成10W呢纠永?
結(jié)果:耗時(shí) = 5755,數(shù)據(jù)容量 = 100000,執(zhí)行次數(shù) = 100000
這就夸張了吧鬓长,5.7秒,這還是去掉了 r1.nextInt()中的限制渺蒿,如果加上限制痢士,將會(huì)更慢。
優(yōu)化
既然要不重復(fù)茂装,那么有一個(gè)集合再適合不過了怠蹂,那就是Set,Set的特性就是內(nèi)部的值全部都是唯一的少态,若相等則會(huì)覆蓋掉原來的城侧,于是我們使用HashSet做測試
long startTime = System.currentTimeMillis(); // 開始測試時(shí)間
Set<Integer> setlist = new HashSet<>();
Random random = new Random();
int i = 0;// 用來驗(yàn)證執(zhí)行了多少次
while (setlist.size() < number) {
setlist.add(random.nextInt());// 由于set的特性,若隨機(jī)數(shù)一樣彼妻,則會(huì)覆蓋原來的數(shù)
i++;
}
long endTime = System.currentTimeMillis(); // 獲取結(jié)束時(shí)間
System.out.println("耗時(shí) = " + (endTime - startTime) + ",數(shù)據(jù)容量 = "
+ setlist.size() + ",執(zhí)行次數(shù) = " + i);
結(jié)果:耗時(shí) = 31,數(shù)據(jù)容量 = 100000,執(zhí)行次數(shù) = 100002
和上面用list的數(shù)據(jù)量一樣嫌佑,但是耗時(shí)只有31毫秒豆茫,速度相差近20倍,接下來我們測試給隨機(jī)數(shù)加個(gè)限制屋摇,隨機(jī)數(shù)限制10W揩魂,需要9W個(gè)無序隨機(jī)數(shù)
結(jié)果:List耗時(shí) = 12751,數(shù)據(jù)容量 = 90000,執(zhí)行次數(shù) = 231006
結(jié)果:Set耗時(shí) = 37,數(shù)據(jù)容量 = 90000,執(zhí)行次數(shù) = 231043
相差近400倍