提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
敲代码敲累了?来打一注双色球乐呵乐呵?
一、代码实现
1.添加依赖及引入库
代码如下(示例):
<dependencies>
<!-- hutool工具类-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.6</version>
</dependency>
<!-- google java类库-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
</dependencies>
import cn.hutool.core.util.RandomUtil;
import com.google.common.collect.Lists;
import java.util.List;
import java.util.Scanner;
2.功能实现
代码如下(示例):
public class DoubleColorBall {
/**
* 主方法
*/
public static void main(String[] args) {
System.out.println("请输入彩票注数:");
Scanner scanner = new Scanner(System.in);
int number = scanner.nextInt();
getDoubleColorBallNumber(number);
}
/**
* 获取多注双色球号码
*/
public static void getDoubleColorBallNumber(int num) {
System.out.println("随机生成" + num + "注双色球号码为:");
String resultNumber = "";
for (int i = 0; i < num; i++) {
System.out.println("【" + (i + 1) + "】 " + resultNumber + getDoubleColorBallNumber());
}
}
/**
* 获取单注双色球号码
*/
public static String getDoubleColorBallNumber() {
String resultNumber = "";
for (int i = 0; i < 6; i++) {
String ballNumber = RandomUtil.randomEle(getRedBalls()) + "\t";
resultNumber = resultNumber + ballNumber;
}
return resultNumber + RandomUtil.randomEle(getBlueBalls());
}
/**
* 获取红球球号集合
*/
public static List<String> getRedBalls() {
return getBalls(33);
}
/**
* 获取蓝球球号集合
*/
public static List<String> getBlueBalls() {
return getBalls(16);
}
/**
* 获取球号集合
*/
public static List<String> getBalls(int num) {
List<String> redBalls = Lists.newArrayList();
for (int i = 1; i <= num; i++) {
int length = String.valueOf(num).length();
String str = String.format("%0" + length + "d", i);
System.out.println(str);
redBalls.add(str);
}
return redBalls;
}
}
二、功能分析
(1)Lists.newArrayList()方法
在代码中,选择调用google工具类下的Lists.newArrayList()方法来创建保存不同球色的球号集合,该方法源码如下:
public static <E> ArrayList<E> newArrayList() {
return new ArrayList();
}
其形式类似于正常的list创建,它能自动推导尖括号里的数据类型。但在 Java 7 之后,都允许类型推断,在运行时没有区别。Java8 的new ArrayList<>()的<>里面可以不写类型,会自行推导数据类型。
不过该方法还拥有丰富的重载,以及相应的扩展方法:
Lists.newArrayList(E... elements)
Lists.newArrayList(Iterable<? extends E> elements)
Lists.newArrayList(Iterator<? extends E> elements)
List<T> exactly = Lists.newArrayListWithCapacity( 100 );
List<T> approx = Lists.newArrayListWithExpectedSize( 100 );
-
如果你确定你的容器装多少个,不会改变,一般直接使用
newArrayListWithCapacity()
,如果容器超过定义size,它会自动扩容,不用担心容量不够。扩容后,会将原来的数组复制到新的数组中,但扩容会带来一定的性能影响:包括开辟新空间,copy数据,耗时,耗性能 -
如果你的不确定你的容器多少个,但增幅不会太大,使用
newArrayListWithExpectedSize()
,会直接创建一个指定size的容器,但它会通过一条公式计算来进行扩容 (
5L + (long)arraySize + (long)(arraySize / 10)
),例如,创建一个10个size的容器,那么 5+10 + (10/10) = 16,当容器添加第17个数据时,这个容器才会进行扩容,优点:节约内存,节约时间,节约性能
RandomUtil.randomEle()方法
调用线路:
randomEle(List<T> list)
-> randomEle(List<T> list, int limit)
-> list.get(randomInt(int limit))
-> getRandom().nextInt(int limit)
-> ThreadLocalRandom getRandom()
public static <T> T randomEle(List<T> list) {
return randomEle(list, list.size());
}
public static <T> T randomEle(List<T> list, int limit) {
return list.get(randomInt(limit));
}
public static int randomInt(int limit) {
return getRandom().nextInt(limit);
}
public static ThreadLocalRandom getRandom() {
return ThreadLocalRandom.current();
}
/**
* Returns a pseudorandom {@code int} value between zero (inclusive)
* and the specified bound (exclusive).
*
* @param bound the upper bound (exclusive). Must be positive.
* @return a pseudorandom {@code int} value between zero
* (inclusive) and the bound (exclusive)
* @throws IllegalArgumentException if {@code bound} is not positive
*/
public int nextInt(int bound) {
if (bound <= 0)
throw new IllegalArgumentException(BAD_BOUND);
int r = mix32(nextSeed());
int m = bound - 1;
if ((bound & m) == 0) // power of two
r &= m;
else { // reject over-represented candidates
for (int u = r >>> 1;
u + m - (r = u % bound) < 0;
u = mix32(nextSeed()) >>> 1)
;
}
return r;
}
Java ThreadLocalRandom 类的 current() 方法返回当前线程的 ThreadLocalRandom,避免了原先的
Java.util.Random 类在多线程情况下,其它线程不断 CAS 自旋,并重写了其nextInt()方法计算种子