Java:在指定的范圍內生成指定數量的隨機數

          需求:我們需要在三個不同的數字段產生不同數量的隨機數。

          比如:[0, 10) 6個;[10, 20) 2個;[20, 30) 2個。

          以下為測試代碼:


           1 package com.homeland.myapp;
           2 
           3 import java.util.Random;
           4 
           5 
           6 public class RandomSequence {
           7 
           8     public static void main(String[] args) {
           9         RandomGen d1 = new RandomGen(0106);
          10         RandomGen d2 = new RandomGen(10202);
          11         RandomGen d3 = new RandomGen(20302);
          12         Thread t1 = new Thread(d1);
          13         Thread t2 = new Thread(d2);
          14         Thread t3 = new Thread(d3);
          15         t1.start();
          16         t2.start();
          17         t3.start();
          18     }
          19 
          20 }
          21 
          22 class RandomGen implements Runnable {
          23     Random r = new Random();
          24     int start, end, num;
          25     
          26     public RandomGen(int end) {
          27         this.end = end;
          28     }
          29     
          30     public RandomGen(int start, int end) {
          31         this.start = start;
          32         this.end = end;
          33     }
          34     
          35     public RandomGen(int start, int end, int num) {
          36         this.start = start;
          37         this.end = end;
          38         this.num = num;
          39     }
          40     
          41     @Override
          42     public void run() {
          43         int c = 0;
          44         for (int i = 0; c < num; i++) {
          45             int a = r.nextInt(end);
          46             if (a >= start) {
          47                 System.out.println("Number " + i + " is: " + a);
          48                 c++;
          49             }
          50         }
          51         System.out.println("-----------------------");
          52     }
          53 }

          以上三個不同的數字段都只包括第一個數字,不包括最后一個。也即,不包含上限。

          以下為測試結果:


           1 Number 0 is: 1
           2 Number 1 is: 5
           3 Number 2 is: 0
           4 Number 3 is: 7
           5 Number 4 is: 6
           6 Number 5 is: 8
           7 -----------------------
           8 Number 12 is: 26
           9 Number 13 is: 28
          10 -----------------------
          11 Number 0 is: 10
          12 Number 4 is: 11
          13 -----------------------
          考慮到去掉重復的數字,代碼作如下修改:

           1 package com.homeland.myapp;
           2 
           3 import java.util.HashSet;
           4 import java.util.Random;
           5 import java.util.Set;
           6 
           7 
           8 public class RandomSequence {
           9 
          10     public static void main(String[] args) {
          11         RandomGen d1 = new RandomGen(0106);
          12         RandomGen d2 = new RandomGen(10202);
          13         RandomGen d3 = new RandomGen(20302);
          14         Thread t1 = new Thread(d1);
          15         Thread t2 = new Thread(d2);
          16         Thread t3 = new Thread(d3);
          17         t1.start();
          18         t2.start();
          19         t3.start();
          20     }
          21 
          22 }
          23 
          24 class RandomGen implements Runnable {
          25     Random r = new Random();
          26     int start, end, num;
          27     
          28     public RandomGen(int end) {
          29         this.end = end;
          30     }
          31     
          32     public RandomGen(int start, int end) {
          33         this.start = start;
          34         this.end = end;
          35     }
          36     
          37     public RandomGen(int start, int end, int num) {
          38         this.start = start;
          39         this.end = end;
          40         this.num = num;
          41     }
          42     
          43     @Override
          44     public void run() {
          45         Set<Integer> s = new HashSet<Integer>();
          46         for (int i = 0; s.size() < num; i++) {
          47             int a = r.nextInt(end);
          48             if (a >= start) {
          49                 s.add(a);
          50             }
          51         }
          52         System.out.println("there are "+ num +" numbers in range: [" + start + "" + end + "]:\n");
          53         System.out.println(s.toString());
          54         System.out.println("-----------------------");
          55     }
          56 }
          其中一組結果如下:

           1 there are 6 numbers in range: [010]:
           2 
           3 [025689]
           4 -----------------------
           5 there are 2 numbers in range: [2030]:
           6 
           7 [2226]
           8 -----------------------
           9 there are 2 numbers in range: [1020]:
          10 
          11 [1113]
          12 -----------------------
          13 
          我修改了代碼,在某個位置上加入了syncronized關鍵字,還有用循環來控制線程的產生:

           1 package com.homeland.myapp;
           2 
           3 import java.util.HashSet;
           4 import java.util.Random;
           5 import java.util.Set;
           6 
           7 public class RandomSequence {
           8 
           9     public static void main(String[] args) {
          10         
          11         int a[][] = {
          12                 {0106}, {10202}, {20304}, 
          13                 {30403}, {40505}, {50607}, 
          14                 {60708}, {70809}, {80904}, {901007}};
          15         
          16         for (int i = 0; i < a.length; i++) {
          17             RandomGen d = new RandomGen(a[i][0], a[i][1], a[i][2]);
          18             Thread t = new Thread(d);
          19             t.start();
          20         }
          21     }
          22 
          23 }
          24 
          25 class RandomGen implements Runnable {
          26     Random r = new Random();
          27     int start, end, num;
          28     Set<Integer> s = new HashSet<Integer>();
          29     
          30     public RandomGen(int end) {
          31         this.end = end;
          32     }
          33     
          34     public RandomGen(int start, int end) {
          35         this.start = start;
          36         this.end = end;
          37     }
          38     
          39     public RandomGen(int start, int end, int num) {
          40         this.start = start;
          41         this.end = end;
          42         this.num = num;
          43     }
          44     
          45     @Override
          46     public void run() {
          47         synchronized (s) {
          48             for (int i = 0; s.size() < num; i++) {
          49                 int a = r.nextInt(end);
          50                 if (a >= start) {
          51                     s.add(a);
          52                 }
          53             }
          54             System.out.println("there are "+ num +" numbers in range: [" + start + "" + end + "]:\n");
          55             System.out.println(s.toString());
          56             System.out.println("-----------------------");
          57         }// sync
          58     }
          59 }
          但是,我得到如下結果:

           1 there are 4 numbers in range: [2030]:
           2 
           3 there are 3 numbers in range: [3040]:
           4 
           5 [353930]
           6 -----------------------
           7 there are 6 numbers in range: [010]:
           8 
           9 [012679]
          10 -----------------------
          11 there are 2 numbers in range: [1020]:
          12 
          13 [1612]
          14 -----------------------
          15 there are 7 numbers in range: [5060]:
          16 
          17 [51505553525958]
          18 -----------------------
          19 [21202426]
          20 -----------------------
          21 there are 9 numbers in range: [7080]:
          22 
          23 [707176777972737475]
          24 -----------------------
          25 there are 5 numbers in range: [4050]:
          26 
          27 [4843404645]
          28 -----------------------
          29 there are 7 numbers in range: [90100]:
          30 
          31 [98999693959490]
          32 -----------------------
          33 there are 8 numbers in range: [6070]:
          34 
          35 [6869646566676260]
          36 -----------------------
          37 there are 4 numbers in range: [8090]:
          38 
          39 [84878389]
          40 -----------------------
          看起來某些部分的輸出時交錯的。看來我需要另外一種控制機制。

          這個控制機制就是:


          1 Thread.sleep(5000);
          把這句放到上面代碼中的main()方法的循環中去。

          上面的Thread.sleep(5000)不是沒有問題的。你可以試想一下,如果數字的范圍很大呢?

          所以,問題的關鍵是:如何保證線程同步或者說線程對共享資源的互斥訪問呢?把代碼做如下修改:


           1 package com.homeland.myapp;
           2 
           3 import java.util.HashSet;
           4 import java.util.Random;
           5 import java.util.Set;
           6 
           7 public class RandomSequence {
           8 
           9     public static void main(String[] args) throws Exception {
          10         
          11         int a[][] = {
          12                 {0106}, {10202}, {20304}, 
          13                 {30403}, {40505}, {50607}, 
          14                 {60708}, {70809}, {80904}, {901007}};
          15         
          16         for (int i = 0; i < a.length; i++) {
          17             RandomGen d = new RandomGen(a[i][0], a[i][1], a[i][2]);
          18             Thread t = new Thread(d);
          19             t.start();
          20             Thread.sleep(1);
          21         }
          22     }
          23 
          24 }
          25 
          26 class RandomGen implements Runnable {
          27     Random r = new Random();
          28     int start, end, num;
          29     private Set<Integer> s = new HashSet<Integer>();
          30     private static Object lock = new Object();
          31     
          32     public RandomGen(int end) {
          33         this.end = end;
          34     }
          35     
          36     public RandomGen(int start, int end) {
          37         this.start = start;
          38         this.end = end;
          39     }
          40     
          41     public RandomGen(int start, int end, int num) {
          42         this.start = start;
          43         this.end = end;
          44         this.num = num;
          45     }
          46     
          47     
          48     @Override
          49     public void run() {
          50         synchronized (lock) {
          51             for (int i = 0; s.size() < num; i++) {
          52                 int a = r.nextInt(end);
          53                 if (a >= start) {
          54                     s.add(a);
          55                 }
          56             }
          57             System.out.println("there are "+ num +" numbers in range: [" + start + "" + end + "]:\n");
          58             System.out.println(s.toString());
          59             System.out.println("-----------------------");
          60         }// sync
          61     }
          62 }
          你木有看錯!靜態類成員被所有類實例共享。關鍵的一句:

          1 private static Object lock = new Object();
          當然,你也可以這么改:

           1 package com.homeland.myapp;
           2 
           3 import java.util.HashSet;
           4 import java.util.Random;
           5 import java.util.Set;
           6 
           7 public class RandomSequence {
           8 
           9     public static void main(String[] args) throws Exception {
          10         
          11         int a[][] = {
          12                 {0106}, {10202}, {20304}, 
          13                 {30403}, {40505}, {50607}, 
          14                 {60708}, {70809}, {80904}, {901007}};
          15         
          16         for (int i = 0; i < a.length; i++) {
          17             RandomGen d = new RandomGen(a[i][0], a[i][1], a[i][2]);
          18             Thread t = new Thread(d);
          19             t.start();
          20             Thread.sleep(1);
          21         }
          22     }
          23 
          24 }
          25 
          26 class RandomGen implements Runnable {
          27     static final Random r = new Random();
          28     static int start, end, num;
          29     private static Set<Integer> s = new HashSet<Integer>();
          30     
          31     public RandomGen(int end) {
          32         this.end = end;
          33     }
          34     
          35     public RandomGen(int start, int end) {
          36         this.start = start;
          37         this.end = end;
          38     }
          39     
          40     public RandomGen(int start, int end, int num) {
          41         this.start = start;
          42         this.end = end;
          43         this.num = num;
          44     }
          45     
          46     private static synchronized void printSequence() {
          47         for (int i = 0; s.size() < num; i++) {
          48             int a = r.nextInt(end);
          49             if (a >= start) {
          50                 s.add(a);
          51             }
          52         }
          53         System.out.println("there are "+ num +" numbers in range: [" + start + "" + end + "]:\n");
          54         System.out.println(s.toString());
          55         System.out.println("-----------------------");
          56     }
          57     
          58     @Override
          59     public void run() {
          60         printSequence();
          61     }
          62 }
          需要注意下,后面的靜態方法會產生類似這樣的結果:

           1 there are 2 numbers in range: [1020]:
           2 
           3 [183]
           4 -----------------------
           5 there are 4 numbers in range: [2030]:
           6 
           7 [1832023]
           8 -----------------------
           9 there are 4 numbers in range: [2030]:
          10 
          11 [1832023]
          12 -----------------------
          13 there are 3 numbers in range: [3040]:
          14 
          15 [1832023]
          16 -----------------------
          17 there are 5 numbers in range: [4050]:
          18 
          19 [183202342]
          20 -----------------------
          21 there are 7 numbers in range: [5060]:
          22 
          23 [1832023425857]
          24 -----------------------
          25 there are 8 numbers in range: [6070]:
          26 
          27 [183652023425857]
          28 -----------------------
          29 there are 9 numbers in range: [7080]:
          30 
          31 [18365202376425857]
          32 -----------------------
          33 there are 4 numbers in range: [8090]:
          34 
          35 [18365202376425857]
          36 -----------------------
          37 there are 7 numbers in range: [90100]:
          38 
          39 [18365202376425857]
          40 -----------------------
          41 
          所以,你需要這么修改代碼:

           1 package com.homeland.myapp;
           2 
           3 import java.util.HashSet;
           4 import java.util.Random;
           5 import java.util.Set;
           6 
           7 public class RandomSequence {
           8 
           9     public static void main(String[] args) throws Exception {
          10         
          11         int a[][] = {
          12                 {0106}, {10202}, {20304}, 
          13                 {30403}, {40505}, {50607}, 
          14                 {60708}, {70809}, {80904}, {901007}};
          15         
          16         for (int i = 0; i < a.length; i++) {
          17             RandomGen d = new RandomGen(a[i][0], a[i][1], a[i][2]);
          18             Thread t = new Thread(d);
          19             t.start();
          20             Thread.sleep(1);
          21         }
          22     }
          23 
          24 }
          25 
          26 class RandomGen implements Runnable {
          27     static final Random r = new Random();
          28     int start, end, num;
          29     
          30     public RandomGen(int end) {
          31         this.end = end;
          32     }
          33     
          34     public RandomGen(int start, int end) {
          35         this.start = start;
          36         this.end = end;
          37     }
          38     
          39     public RandomGen(int start, int end, int num) {
          40         this.start = start;
          41         this.end = end;
          42         this.num = num;
          43     }
          44     
          45     private static synchronized void printSequence(int start, int end, int num) {
          46         final Set<Integer> s = new HashSet<Integer>();
          47         for (; s.size() < num;) {
          48             int a = r.nextInt(end);
          49             if (a >= start) {
          50                 s.add(a);
          51             }
          52         }
          53         System.out.println("there are "+ num +" numbers in range: [" + start + "" + end + "]:\n");
          54         System.out.println(s.toString());
          55         System.out.println("-----------------------");
          56     }
          57     
          58     @Override
          59     public void run() {
          60         printSequence(start, end, num);
          61     }
          62 }
          我得到的結果類似這種:

           1 there are 6 numbers in range: [010]:
           2 
           3 [034678]
           4 -----------------------
           5 there are 2 numbers in range: [1020]:
           6 
           7 [1713]
           8 -----------------------
           9 there are 4 numbers in range: [2030]:
          10 
          11 [20252628]
          12 -----------------------
          13 there are 3 numbers in range: [3040]:
          14 
          15 [333830]
          16 -----------------------
          17 there are 5 numbers in range: [4050]:
          18 
          19 [4340464745]
          20 -----------------------
          21 there are 7 numbers in range: [5060]:
          22 
          23 [55545359585756]
          24 -----------------------
          25 there are 8 numbers in range: [6070]:
          26 
          27 [6869646663626160]
          28 -----------------------
          29 there are 9 numbers in range: [7080]:
          30 
          31 [707176777879727374]
          32 -----------------------
          33 there are 4 numbers in range: [8090]:
          34 
          35 [86808288]
          36 -----------------------
          37 there are 7 numbers in range: [90100]:
          38 
          39 [96979392959490]
          40 -----------------------
          41 
          留個小尾巴:用HashSet去重效率如何呢?

          posted on 2014-05-15 16:05 馬克思.佩恩 閱讀(196) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          導航

          統計

          留言簿

          隨筆檔案

          文章分類

          相冊

          搜索

          最新評論

          主站蜘蛛池模板: 南皮县| 江北区| 图木舒克市| 南郑县| 金乡县| 泗阳县| 富平县| 始兴县| 杭州市| 文登市| 达州市| 新巴尔虎右旗| 中西区| 安平县| 绿春县| 吉隆县| 镇康县| 景泰县| 高雄县| 苗栗市| 门源| 牟定县| 通海县| 库车县| 阿荣旗| 吉木萨尔县| 河津市| 拜泉县| 三都| 汶川县| 鄂托克旗| 墨脱县| 福安市| 榕江县| 磐安县| 安化县| 鄂托克旗| 龙南县| 布拖县| 谢通门县| 台北市|