方法1
(數據類型)(最小值+Math.random()*(最大值-最小值+1)) 例: (int)(1+Math.random()*(10-1+1)) 從1到10的int型隨數
方法2
得到隨機數 for (int i=0;i<30;i++) {System.out.println((int)(1+Math.random()*10));} (int)(1+Math.random()*10) 經過java.Math包的random方法獲得1-10的int隨機數 公式是:最小值---最大值(整數)的隨機數 (類型)最小值+Math.random()*最大值
方法3
Random ra =new Random(); for (int i=0;i<30;i++) {System.out.println(ra.nextInt(10)+1);} 經過java.util包中的Random類的nextInt方法來獲得1-10的int隨機數
生成0到1之間的任意隨機小數:
生成[0,d)區間的隨機小數,d爲任意正的小數,則只須要將nextDouble方法的返回值乘以d便可。java [n1,n2]算法 也就是 ra.nextDouble() * (n2-n1)+n1數據庫
|
java產生隨機數的幾種方式
一.在j2se裏咱們可使用Math.random()方法來產生一個隨機數,這個產生的隨機數是0-1之間的一個double,咱們能夠把他乘以必定的數,好比說乘以100,他就是個100之內的隨機,這個在j2me中沒有。編程
二.在java.util這個包裏面提供了一個Random的類,咱們能夠新建一個Random的對象來產生隨機數,他能夠產生隨機整數、隨機float、隨機double,隨機long,這個也是咱們在j2me的程序裏常常用的一個取隨機數的方法。數組
三.在咱們的System類中有一個currentTimeMillis()方法,這個方法返回一個從1970年1月1號0點0分0秒到目前的一個毫秒數,返回類型是long,咱們能夠拿他做爲一個隨機數,咱們能夠拿他對一些數取模,就能夠把他限制在一個範圍以內啦app
其實在Random的默認構造方法裏也是使用上面第三種方法進行隨機數的產生的dom
對於方法二中的Random類有如下說明:函數
java.util.Random類有兩種方式構建方式:帶種子和不帶種子工具
不帶種子:
此種方式將會返回隨機的數字,每次運行結果不同測試
public class RandomTest {
public static void main(String[] args) {
java.util.Random r=new java.util.Random();
for(int i=0;i<10;i++){
System.out.println(r.nextInt());
}
}
帶種子:
此種方式,不管程序運行多少次,返回結果都是同樣的
public static void main(String[] args) {
java.util.Random r=new java.util.Random(10);
for(int i=0;i<10;i++){
System.out.println(r.nextInt());
}
}
兩種方式的差異在於
(1) 首先請打開Java Doc,咱們會看到Random類的說明:
此類的實例用於生成僞隨機數流,此類使用 48 位的種子,該種子可使用線性同餘公式對其進行修改(請參閱 Donald Knuth 的《The Art of Computer Programming, Volume 2》,第 3.2.1 節)。
若是用相同的種子建立兩個 Random 實例,則對每一個實例進行相同的方法調用序列,它們將生成並返回相同的數字序列。爲了保證明現這種特性,咱們爲類Random指定了特定的算法。爲了 Java 代碼的徹底可移植性,Java 實現必須讓類 Random 使用此處所示的全部算法。可是容許 Random 類的子類使用其餘算法,只要其符合全部方法的常規協定便可。
Java Doc對Random類已經解釋得很是明白,咱們的測試也驗證了這一點。
(2) 若是沒有提供種子數,Random實例的種子數將是當前時間的毫秒數,能夠經過System.currentTimeMillis()來得到當前時間的毫秒數。打開JDK的源代碼,咱們能夠很是明確地看到這一點。
public Random() { this(System.currentTimeMillis()); }
另外:
random對象的nextInt(),nextInt(int n)方法的說明:
int nextInt()
返回下一個僞隨機數,它是此隨機數生成器的序列中均勻分佈的 int 值。
int nextInt(int n)
返回一個僞隨機數,它是今後隨機數生成器的序列中取出的、在 0(包括)和指定值(不包括)之間均勻分佈的 int值。
隨機數在實際中使用很普遍,好比要隨即生成一個固定長度的字符串、數字。或者隨即生成一個不定長度的數字、或者進行一個模擬的隨機選擇等等。Java提供了最基本的工具,能夠幫助開發者來實現這一切。
1、Java隨機數的產生方式
在Java中,隨機數的概念從廣義上將,有三種。
一、經過System.currentTimeMillis()來獲取一個當前時間毫秒數的long型數字。
二、經過Math.random()返回一個0到1之間的double值。
三、經過Random類來產生一個隨機數,這個是專業的Random工具類,功能強大。
2、Random類API說明
一、Java API說明
Random類的實例用於生成僞隨機數流。此類使用 48 位的種子,使用線性同餘公式對其進行修改(請參閱 Donald Knuth 的《The Art of Computer Programming, Volume 2》,第 3.2.1 節)。
若是用相同的種子建立兩個 Random 實例,則對每一個實例進行相同的方法調用序列,它們將生成並返回相同的數字序列。爲了保證屬性的實現,爲類 Random 指定了特定的算法。
不少應用程序會發現 Math 類中的 random 方法更易於使用。
二、方法摘要
Random()
建立一個新的隨機數生成器。
Random(long seed)
使用單個 long 種子建立一個新隨機數生成器: public Random(long seed) { setSeed(seed); } next 方法使用它來保存隨機數生成器的狀態。
protected int next(int bits)
生成下一個僞隨機數。
boolean nextBoolean()
返回下一個僞隨機數,它是今後隨機數生成器的序列中取出的、均勻分佈的 boolean 值。
void nextBytes(byte[] bytes)
生成隨機字節並將其置於用戶提供的字節數組中。
double nextDouble()
返回下一個僞隨機數,它是今後隨機數生成器的序列中取出的、在 0.0 和 1.0之間均勻分佈的 double 值。
float nextFloat()
返回下一個僞隨機數,它是今後隨機數生成器的序列中取出的、在 0.0 和 1.0 之間均勻分佈的 float 值。
double nextGaussian()
返回下一個僞隨機數,它是今後隨機數生成器的序列中取出的、呈高斯(「正常地」)分佈的 double 值,其平均值是 0.0,標準誤差是 1.0。
int nextInt()
返回下一個僞隨機數,它是此隨機數生成器的序列中均勻分佈的 int 值。
int nextInt(int n)
返回一個僞隨機數,它是今後隨機數生成器的序列中取出的、在 0(包括)和指定值(不包括)之間均勻分佈的 int值。
long nextLong()
返回下一個僞隨機數,它是今後隨機數生成器的序列中取出的、均勻分佈的 long 值。
void setSeed(long seed)
使用單個 long 種子設置此隨機數生成器的種子。
3、Random類使用說明
一、帶種子與不帶種子的區別Random類使用的根本是策略分帶種子和不帶種子的Random的實例。
通俗說,二者的區別是:帶種子的,每次運行生成的結果都是同樣的。
不帶種子的,每次運行生成的都是隨機的,沒有規律可言。
二、建立不帶種子的Random對象
Random random = new Random();
三、建立不帶種子的Random對象有兩種方法:
1) Random random = new Random(555L);
2) Random random = new Random();random.setSeed(555L);
4、測試
經過一個例子說明上面的用法
import java.util.Random;
public class TestRandomNum {
public static void main(String[] args) {
randomTest();
testNoSeed();
testSeed1();
testSeed2();
}
public static void randomTest() {
System.out.println("--------------test()--------------");
//返回以毫秒爲單位的當前時間。
long r1 = System.currentTimeMillis();
//返回帶正號的 double 值,大於或等於 0.0,小於 1.0。
double r2 = Math.random();
//經過Random類來獲取下一個隨機的整數
int r3 = new Random().nextInt();
System.out.println("r1 = " + r1);
System.out.println("r3 = " + r2);
System.out.println("r2 = " + r3);
}
public static void testNoSeed() {
System.out.println("--------------testNoSeed()--------------");
//建立不帶種子的測試Random對象
Random random = new Random();
for (int i = 0; i < 3; i++) {
System.out.println(random.nextInt());
}
}
public static void testSeed1() {
System.out.println("--------------testSeed1()--------------");
//建立帶種子的測試Random對象
Random random = new Random(555L);
for (int i = 0; i < 3; i++) {
System.out.println(random.nextInt());
}
}
public static void testSeed2() {
System.out.println("--------------testSeed2()--------------");
//建立帶種子的測試Random對象
Random random = new Random();
random.setSeed(555L);
for (int i = 0; i < 3; i++) {
System.out.println(random.nextInt());
}
}
}
運行結果:
--------------test()--------------
r1 = 1227108626582
r3 = 0.5324887850155043
r2 = -368083737
--------------testNoSeed()--------------
809503475
1585541532
-645134204
--------------testSeed1()--------------
-1367481220
292886146
-1462441651
--------------testSeed2()--------------
-1367481220
292886146
-1462441651
Process finished with exit code 0
經過testSeed1()與testSeed2()方法的結果能夠看到,兩個打印結果相同,由於他們種子相同,再運行一次,結果仍是同樣的,這就是帶種子隨機數的特性。
而不帶種子的,每次運行結果都是隨機的。
5、綜合應用
下面經過最近寫的一個隨機數工具類來展現用法:
import java.util.Random;
public class RandomUtils {
public static final String allChar = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static final String letterChar = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static final String numberChar = "0123456789";
public static String generateString(int length) {
StringBuffer sb = new StringBuffer();
Random random = new Random();
for (int i = 0; i < length; i++) {
sb.append(allChar.charAt(random.nextInt(allChar.length())));
}
return sb.toString();
}
public static String generateMixString(int length) {
StringBuffer sb = new StringBuffer();
Random random = new Random();
for (int i = 0; i < length; i++) {
sb.append(allChar.charAt(random.nextInt(letterChar.length())));
}
return sb.toString();
}
public static String generateLowerString(int length) {
return generateMixString(length).toLowerCase();
}
public static String generateUpperString(int length) {
return generateMixString(length).toUpperCase();
}
public static String generateZeroString(int length) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
sb.append('0');
}
return sb.toString();
}
public static String toFixdLengthString(long num, int fixdlenth) {
StringBuffer sb = new StringBuffer();
String strNum = String.valueOf(num);
if (fixdlenth - strNum.length() >= 0) {
sb.append(generateZeroString(fixdlenth - strNum.length()));
} else {
throw new RuntimeException("將數字" + num + "轉化爲長度爲" + fixdlenth + "的字符串發生異常!");
}
sb.append(strNum);
return sb.toString();
}
public static String toFixdLengthString(int num, int fixdlenth) {
StringBuffer sb = new StringBuffer();
String strNum = String.valueOf(num);
if (fixdlenth - strNum.length() >= 0) {
sb.append(generateZeroString(fixdlenth - strNum.length()));
} else {
throw new RuntimeException("將數字" + num + "轉化爲長度爲" + fixdlenth + "的字符串發生異常!");
}
sb.append(strNum);
return sb.toString();
}
public static void main(String[] args) {
System.out.println(generateString(15));
System.out.println(generateMixString(15));
System.out.println(generateLowerString(15));
System.out.println(generateUpperString(15));
System.out.println(generateZeroString(15));
System.out.println(toFixdLengthString(123, 15));
System.out.println(toFixdLengthString(123L, 15));
}
}
運行結果:
vWMBPiNbzfGCpHG
23hyraHdJkKPwMv
tigowetbwkm1nde
BPZ1KNEJPHB115N
000000000000000
000000000000123
000000000000123
Process finished with exit code 0
6、總結
一、隨機數很經常使用,在Java有三種產生方式,以Random隨機數的使用最爲複雜。
二、Random類對象有是否帶種子之分,帶種子的只要種子相同,屢次運行,生成隨機數的結果老是那樣。
三、帶種子隨機數的帶種子的對象建立方式有兩種,效果同樣。可是帶種子的隨機數用處彷佛不大。
四、Random的功能涵蓋了Math.random()的功能。
五、能夠經過隨機數去作實現隨機字符串等複雜的隨機數據。
六、不要研究不重複的隨機數,意義不大。
在Java 中咱們可使用java.util.Random類來產生一個隨機數發生器。它有兩種形式的構造函數,分別是Random()和Random(long seed)。Random()使用當前時間即System.currentTimeMillis()做爲發生器的種子,Random(long seed)使用指定的seed做爲發生器的種子。
隨機數發生器(Random)對象產生之後,經過調用不一樣的method:nextInt()、nextLong()、nextFloat()、nextDouble()等得到不一樣類型隨機數。
1>生成隨機數
Random random = new Random();
Random random = new Random(100);//指定種子數100
random調用不一樣的方法,得到隨機數。
若是2個Random對象使用相同的種子(好比都是100),而且以相同的順序調用相同的函數,那它們返回值徹底相同。以下面代碼中兩個Random對象的輸出徹底相同
import java.util.*;
class TestRandom {
public static void main(String[] args) {
Random random1 = new Random(100);
System.out.println(random1.nextInt());
System.out.println(random1.nextFloat());
System.out.println(random1.nextBoolean());
Random random2 = new Random(100);
System.out.println(random2.nextInt());
System.out.println(random2.nextFloat());
System.out.println(random2.nextBoolean());
}
}
2>指定範圍內的隨機數
隨機數控制在某個範圍內,使用模數運算符%
import java.util.*;
class TestRandom {
public static void main(String[] args) {
Random random = new Random();
for(int i = 0; i < 10;i++) {
System.out.println(Math.abs(random.nextInt()));
}
}
}
得到的隨機數有正有負的,用Math.abs使獲取數據範圍爲非負數
3>獲取指定範圍內的不重複隨機數
import java.util.*;
class TestRandom {
public static void main(String[] args) {
int[] intRet = new int[6];
int intRd = 0; //存放隨機數
int count = 0; //記錄生成的隨機數個數
int flag = 0; //是否已經生成過標誌
while(count<6){
Random rdm = new Random(System.currentTimeMillis());
intRd = Math.abs(rdm.nextInt())2+1;
for(int i=0;i<count;i++){
if(intRet[i]==intRd){
flag = 1;
break;
}else{
flag = 0;
}
}
if(flag==0){
intRet[count] = intRd;
count++;
}
}
for(int t=0;t<6;t++){
System.out.println(t+"->"+intRet[t]);
}
}
}
Java中的隨機數是否能夠重複?Java中產生的隨機數可否能夠用來產生數據庫主鍵?帶着這個問題,咱們作了一系列測試。
1.測試一: 使用不帶參數的Random()構造函數
public class RandomTest {
public static void main(String[] args) {
java.util.Random r=new java.util.Random();
for(int i=0;i<10;i++){
System.out.println(r.nextInt());
}
}
}
程序運行結果:
-1761145445
-1070533012
216216989
-910884656
-1408725314
-1091802870
1681403823
-1099867456
347034376
-1277853157
再次運行該程序:
-169416241
220377062
-1140589550
-1364404766
-1088116756
2134626361
-546049728
1132916742
-1522319721
1787867608
從上面的測試咱們能夠看出,使用不帶參數的Random()構造函數產生的隨機數不會重複。那麼,什麼狀況下Java會產生重複的隨機數呢?且看下面的測試。
2. 測試二:爲Random設置種子數
public class RandomTest_Repeat {
public static void main(String[] args) {
java.util.Random r=new java.util.Random(10);
for(int i=0;i<10;i++){
System.out.println(r.nextInt());
}
}
}
不管程序運行多少次,其結果老是:
-1157793070
1913984760
1107254586
1773446580
254270492
-1408064384
1048475594
1581279777
-778209333
1532292428
甚至在不一樣的機器上測試,測試結果也不會改變!
3.緣由分析:
(1) 首先請打開Java Doc,咱們會看到Random類的說明:
此類的實例用於生成僞隨機數流,此類使用 48 位的種子,該種子可使用線性同餘公式對其進行修改(請參閱 Donald Knuth 的《The Art of Computer Programming, Volume 2》,第 3.2.1 節)。
若是用相同的種子建立兩個 Random 實例,則對每一個實例進行相同的方法調用序列,它們將生成並返回相同的數字序列。爲了保證明現這種特性,咱們爲類Random指定了特定的算法。爲了 Java 代碼的徹底可移植性,Java 實現必須讓類 Random 使用此處所示的全部算法。可是容許 Random 類的子類使用其餘算法,只要其符合全部方法的常規協定便可。
Java Doc對Random類已經解釋得很是明白,咱們的測試也驗證了這一點。
(2) 若是沒有提供種子數,Random實例的種子數將是當前時間的毫秒數,能夠經過System.currentTimeMillis()來得到當前時間的毫秒數。打開JDK的源代碼,咱們能夠很是明確地看到這一點。
public Random() { this(System.currentTimeMillis()); }
4. 結論:
經過上面的測試和分析,咱們會對Random類有較爲深入的理解。同時,我以爲,經過閱讀Java Doc的API文檔,能夠很好地提升咱們的Java編程能力,作到「知其然」;一旦遇到費解的問題,不妨打開Java的源代碼,這樣咱們就能作到「知其因此然」。
--------------------------------------------------------------------------------------------------
java中通常有兩種隨機數,一個是Math中random()方法,一個是Random類。
1、Math.random()
隨即生成0<x<1的小數。
實例:如何寫,生成隨機生成出0~100中的其中一個數呢?
Math.random()返回的只是從0到1之間的小數,若是要50到100,就先放大50倍,即0到50之間,這裏仍是小數,若是要整數,就強制轉換int,而後再加上50即爲50~100.
最終代碼:(int)(Math.random()*50) + 50
2、Random類
Random random = new Random();//默認構造方法
Random random = new Random(1000);//指定種子數字
在進行隨機時,隨機算法的起源數字稱爲種子數(seed),在種子數的基礎上進行必定的變換,從而產生須要的隨機數字。
相同種子數的Random對象,相同次數生成的隨機數字是徹底相同的。也就是說,兩個種子數相同的Random對象,第一次生成的隨機數字徹底相同,第二次生成的隨機數字也徹底相同。
2 、Random類中的經常使用方法
Random 類中的方法比較簡單,每一個方法的功能也很容易理解。須要說明的是,Random類中各方法生成的隨機數字都是均勻分佈的,也就是說區間內部的數字生成的概率是均等的。下面對這些方法作一下基本的介紹:
a 、public boolean nextBoolean()
該方法的做用是生成一個隨機的boolean值,生成true和false的值概率相等,也就是都是50%的概率。
b 、public double nextDouble()
該方法的做用是生成一個隨機的double值,數值介於[0,1.0)之間,這裏中括號表明包含區間端點,小括號表明不包含區間端點,也就是0到1之間的隨機小數,包含0而不包含1.0。
c 、public int nextInt()
該方法的做用是生成一個隨機的int值,該值介於int的區間,也就是-2的31次方到2的31次方-1之間。
若是須要生成指定區間的int值,則須要進行必定的數學變換,具體能夠參看下面的使用示例中的代碼。
d 、public int nextInt(int n)
該方法的做用是生成一個隨機的int值,該值介於[0,n)的區間,也就是0到n之間的隨機int值,包含0而不包含n。
若是想生成指定區間的int值,也須要進行必定的數學變換,具體能夠參看下面的使用示例中的代碼。
e 、public void setSeed(long seed)
該方法的做用是從新設置Random對象中的種子數。設置完種子數之後的Random對象和相同種子數使用new關鍵字建立出的Random對象相同。
3 、Random類使用示例
使用Random類,通常是生成指定區間的隨機數字,下面就一一介紹如何生成對應區間的隨機數字。如下生成隨機數的代碼均使用如下Random對象r進行生成:
Random r = new Random();
a 、生成[0,1.0)區間的小數
double d1 = r.nextDouble();
直接使用nextDouble方法得到。
b、生成[0,5.0)區間的小數
double d2 = r.nextDouble() * 5;
由於nextDouble方法生成的數字區間是[0,1.0),將該區間擴大5倍便是要求的區間。
同理,生成[0,d)區間的隨機小數,d爲任意正的小數,則只須要將nextDouble方法的返回值乘以d便可。
c、生成[1,2.5)區間的小數 [n1,n2]
double d3 = r.nextDouble() * 1.5 + 1;【也就是 r.nextDouble() * (n2-n1)+n1】
生成[1,2.5)區間的隨機小數,則只須要首先生成[0,1.5)區間的隨機數字,而後將生成的隨機數區間加1便可。
同理,生成任意非從0開始的小數區間[d1,d2)範圍的隨機數字(其中d1不等於0),則只須要首先生成[0,d2-d1)區間的隨機數字,而後將生成的隨機數字區間加上d1便可。
d、生成任意整數
int n1 = r.nextInt();
直接使用nextInt方法便可。
e、生成[0,10)區間的整數
int n2 = r.nextInt(10);
n2 = Math.abs(r.nextInt() % 10);
以上兩行代碼都可生成[0,10)區間的整數。
第一種實現使用Random類中的nextInt(int n)方法直接實現。
第二種實現中,首先調用nextInt()方法生成一個任意的int數字,該數字和10取餘之後生成的數字區間爲(-10,10),由於按照數學上的規定餘數的絕對值小於除數,而後再對該區間求絕對值,則獲得的區間就是[0,10)了。
同理,生成任意[0,n)區間的隨機整數,均可以使用以下代碼:
int n2 = r.nextInt(n);
n2 = Math.abs(r.nextInt() % n);
f、生成[0,10]區間的整數
int n3 = r.nextInt(11);
n3 = Math.abs(r.nextInt() % 11);
相對於整數區間,[0,10]區間和[0,11)區間等價,因此即生成[0,11)區間的整數。
g、生成[-3,15)區間的整數
int n4 = r.nextInt(18) - 3; 【也就是 r.nextInt() * (n2-n1)+n1】 n1是個負數
n4 = Math.abs(r.nextInt() % 18) - 3;
生成非從0開始區間的隨機整數,能夠參看上面非從0開始的小數區間實現原理的說明。