import java.util.Arrays;
import java.util.Random;/**
* 随机数生成器,规则: <br>
* 1.11位数字,以'AA'开始;<br>
* 2.数量为90000,范围以内不重复; <br>
* @author YC
*/
public class RanderNumberCreator { Random random; /** 生成随机数组,存放不重复的随机数 */
public String[] createRandomNumber() {
// 随机数个数
int numAmount = 90000;
// 范围内最小值
int initNum = 100000000;
// 随机数种子
int rootNum = 900000000;
// 循环范围
int loopRange = numAmount + 10000;
// 循环指针.记录本次数目
int index = 0; // 存放最终结果的字符串数组
String[] numResultArrays = new String[numAmount];
// 存放临时整型数据的数组,范围大些.
int[] intNums = new int[loopRange]; int[] repeatNums = new int[numAmount]; for (int i = 0; i < loopRange; i++) {
int currentNum = getRandomNumber(rootNum, initNum);
// 如果没有重复数据,应该只会循环numAmount次就跳出
if (index == numAmount)
break;
else if (Arrays.binarySearch(intNums, currentNum) < 0) {
intNums[i] = currentNum;
numResultArrays[i] = "AA" + currentNum;
index++;
} else {
System.err.println("------------ 产生重复数据!");
repeatNums[i] = currentNum;
}
} return numResultArrays;
} /**
* 获取范围内的随机数
*
* @param rootNum
* 范围种子
* @param initNum
* 起始值
*/
protected int getRandomNumber(int rootNum, int initNum) {
random = new Random();
return random.nextInt(rootNum) + initNum;
} public static void main(String[] args) {
String[] results = new RanderNumberCreator().createRandomNumber();
System.err.println(" 随机数组存放: " + results.length);
System.err.println(" 最后一个随机数: " + results[results.length - 1]);
// for(int i=0;i<results.length;i++)
// System.err.println(results[i]);
}}
嘛啊,以前没有怎么看random,查了些资料就写了.有什么bug,请大家指正了.
import java.util.Random;/**
* 随机数生成器,规则: <br>
* 1.11位数字,以'AA'开始;<br>
* 2.数量为90000,范围以内不重复; <br>
* @author YC
*/
public class RanderNumberCreator { Random random; /** 生成随机数组,存放不重复的随机数 */
public String[] createRandomNumber() {
// 随机数个数
int numAmount = 90000;
// 范围内最小值
int initNum = 100000000;
// 随机数种子
int rootNum = 900000000;
// 循环范围
int loopRange = numAmount + 10000;
// 循环指针.记录本次数目
int index = 0; // 存放最终结果的字符串数组
String[] numResultArrays = new String[numAmount];
// 存放临时整型数据的数组,范围大些.
int[] intNums = new int[loopRange]; int[] repeatNums = new int[numAmount]; for (int i = 0; i < loopRange; i++) {
int currentNum = getRandomNumber(rootNum, initNum);
// 如果没有重复数据,应该只会循环numAmount次就跳出
if (index == numAmount)
break;
else if (Arrays.binarySearch(intNums, currentNum) < 0) {
intNums[i] = currentNum;
numResultArrays[i] = "AA" + currentNum;
index++;
} else {
System.err.println("------------ 产生重复数据!");
repeatNums[i] = currentNum;
}
} return numResultArrays;
} /**
* 获取范围内的随机数
*
* @param rootNum
* 范围种子
* @param initNum
* 起始值
*/
protected int getRandomNumber(int rootNum, int initNum) {
random = new Random();
return random.nextInt(rootNum) + initNum;
} public static void main(String[] args) {
String[] results = new RanderNumberCreator().createRandomNumber();
System.err.println(" 随机数组存放: " + results.length);
System.err.println(" 最后一个随机数: " + results[results.length - 1]);
// for(int i=0;i<results.length;i++)
// System.err.println(results[i]);
}}
嘛啊,以前没有怎么看random,查了些资料就写了.有什么bug,请大家指正了.
int numAmount = 90000;
// 范围内最小值
int initNum = 100000000;
// 随机数种子
int rootNum = 900000000;
// 循环范围
int loopRange = numAmount + 10000;
// 循环指针.记录本次数目
int index = 0;这些东西好放参数里控制最好
其次,这样判定重复有无问题,还有没有什么好办法能高效的判定是否数组内有重复,这是需求的重点.
random = new Random();
return random.nextInt(rootNum) + initNum;
}这段代码里的random = new Random();不妥,不用再每次都去创建Random吧;改为在RanderNumberCreator类初始化的时候去创建,如下public class RanderNumberCreator { Random random = new Random();
。。
protected int getRandomNumber(int rootNum, int initNum) {
//random = new Random();
return random.nextInt(rootNum) + initNum;
}在判断重复时,你用的是折半查找那intNums必须是有序的,
else if (Arrays.binarySearch(intNums, currentNum) < 0) {
intNums[i] = currentNum;
numResultArrays[i] = "AA" + currentNum;
index++;
} else {
但是加入intNums是,没有先找好位置,再插入。
你可以改成Hash表的方式去查找,更有效率。如下 HashSet<Integer> intNums = new HashSet<Integer>();
int[] repeatNums = new int[numAmount]; for (int i = 0; i < loopRange; i++) {
int currentNum = getRandomNumber(rootNum, initNum);
// 如果没有重复数据,应该只会循环numAmount次就跳出
if (index == numAmount)
break;
else if (!intNums.contains(Integer.valueOf(currentNum))) {
intNums.add(Integer.valueOf(currentNum));
numResultArrays[i] = "AA" + currentNum;
index++;
} else {
我把1到10000加到List中,然后Collections.shuffle一下,取得时候都取第一个。同时在某个地方记住这个10000第二次我又要20000个随机数的时候,我把10001到30000加到一个List中,然后同上面步骤
现在去跑下你给的修正代码,之前考虑用数组是因为感觉效率好过集合,根据你的建议感觉从数据结构上用hash会好些.
如果是前者,前次的数据是存放在文件还是数据库比较好,我的倾向是写在文件(2010-xx-xx.txt)类似的情况,然后每次生成前先读取再判断,也还请大家给建议.
intNums.add(Integer.valueOf(currentNum));
numResultArrays[i] = "AA" + currentNum;
index++;发现了数组越界异常,修改了代码numResultArrays[index] = "AA" + currentNum;根据blazingfire的提示,下面是修改完成的代码:/**
* 创建随机号码:
*
* @param numAmount
* 随机数个数
* @param initNum
* 范围内最小值
* @param rootNum
* 随机数种子
* */
public String[] createRandomNumber2(int numAmount, int initNum, int rootNum) {
// 循环范围
int loopRange = numAmount + 10000;
// 循环指针.记录本次数目
int index = 0; // 存放最终结果的字符串数组
String[] numResultArrays = new String[numAmount]; HashSet<Integer> intNums = new HashSet<Integer>(); int[] repeatNums = new int[numAmount]; for (int i = 0; i < loopRange; i++) {
int currentNum = getRandomNumber(rootNum, initNum);
// 如果没有重复数据,应该只会循环numAmount次就跳出
if (index == numAmount)
break;
else if (!intNums.contains(Integer.valueOf(currentNum))) {
intNums.add(Integer.valueOf(currentNum));
numResultArrays[index] = "71" + currentNum;
index++;
} else {
System.err.println("------------ 产生重复数据位置:" + index + "[当前随机数:]" + currentNum + ",[当前数组元素值]" + numResultArrays[i]);
repeatNums[i] = currentNum;
}
} return numResultArrays;
} public static void main(String[] args) {
String[] results = new RanderNumberCreator().createRandomNumber2(83000,100000000,900000000);
int length = results.length;
System.err.println(" 随机数组存放: " + length);
System.err.println(" 最后一个随机数: " + results[results.length - 1]); for (int i = 0; i < length; i++) {
if (results[i] == null) {
System.err.println("结果有空值!");
}
}
}
if (index == numAmount)
break;
来结束这个循环,这种代码可读性就不太好了。其实你可以直接返回一个set就可以了,循环判断set是不是够了你要的随机数个数就好,如下代码是重构后的应该对你有用: public Set<String> createRandomNumber2(int numAmount, int initNum, int rootNum) {
Set<String> ret = new HashSet<String>();
while (ret.size() < numAmount) {
//因为set里的元素不会有重复的,直接加就好了,加够了numAmount就不加了
ret.add("71" + getRandomNumber(rootNum, initNum));
}
return ret;
}}如果嫌Set遍历慢,可用ArrayList返回,代码一样可以精简如下: public List<String> createRandomNumber2(int numAmount, int initNum, int rootNum) {
// 存放最终结果的字符串
List<String> ret = new ArrayList<String>(); HashSet<Integer> intNums = new HashSet<Integer>();
while (ret.size() < numAmount) {
int currentNum = getRandomNumber(rootNum, initNum);
if (intNums.add(currentNum)) {
ret.add("71" + currentNum);
}
} return ret;
}
public String[] createRandomNumber2(int numAmount, int initNum, int rootNum) {
// 存放最终结果的字符串
String[] ret = new String[numAmount]; HashSet<Integer> intNums = new HashSet<Integer>();
int index = 0;
while (intNums.size() < numAmount) {
int currentNum = getRandomNumber(rootNum, initNum);
if (intNums.add(currentNum)) {
ret[index++] = "71" + currentNum;
}
} return ret;
}
要注意写有表现力的代码。