场景故事3 点名与大奖
3.1 场景故事
小明上课的教室里一共有两个班,其中一班有30名同学、二班有33名同学。小明
发现老师每次按学号分别在两个班点名6位不同的同学,并且老师每次都是简单地看一
下她的计算机,就能快速、随意地说出6个不同的学号。老师点名现场如图3.1所示。
图3.1 老师点名现场
课程快结束时,小明好奇地问老师:“老师,我发现您的记忆力非常好。您
可以在一班或二班快速、随意地说出6个学号,而且能保证6个学号互不相同。若是
您想要点名20名学生,即快速、随意地说出20个学号,也能保证这20个学号是不同
的吗?您是怎么做到的呢?”
老师笑着对小明说:“我每次点名时,都是用余光看着计算机显示器的屏
幕,是我用自己编写的一个点名程序,来保证从班级里抽取6个不同的学号 。”
小明向老师要了源代码,决定认真研究一下,准备写一个模拟福利彩票抽奖
的程序。小明发现,这学期有12位给自己上课的老师,决定分别给这些老师编号为
1~12。如果是10号老师上课,就设篮球号码是10;然后用自己编写的Java程序随机
场 景 故 事
点名与大奖
3
10 趣懂Java旋律,击破36个难点
得到1~33中的6个数,作为红球号码,再与福利彩票开奖后的大奖做比对,看看自
己的Java程序能否得大奖。
本故事纯属虚构,如有雷同,纯属巧合。
3.2 场景故事的目的
1. 侧重点
java.util包(Java工具包)中的Arrays类提供了许多static方法,可以用类名
Arrays直接调用这些方法。
通过该场景学习Arrays类提供的复制数组和判断数组相等的方法。
(1)数组的复制。
public static int[] copyOfRange(int[] original, int from, int to)
copyOfRange()方法可以把参数original指定的数组中从索引from至to-1的元素复
制到一个新数组中,并返回这个新数组,即新数组的长度为to-from。如果to的值
大于数组original的长度,则新数组的元素从索引original.length-from开始的元素取
默认值。
比如,对于数组a:
int [] a = {1,2,3,4,5,6};
① 复制数组a的部分元素,得到一个新的数组b:
int [] b = Arrays.copyOfRange(a,1,4);
那么,数组b的长度即b.length的值是3。b[0]的值是2, b[1]的值是3, b[2]的值是4。
② 复制数组a的部分元素,得到另一个新的数组:
int [] c = Arrays.copyOfRange(a,4,10);
那么,数组c的长度即c.length的值是6。c[0]的值是5,c[1]的值是6,c[2]至c[5]的值
都是0。
(2)数组的相等判断。
有时需要判断两个类型相同的数组的值是否相同,即二者的长度一样且对应
场景故事3 点名与大奖11
的元素值也相同。
public static boolean equals(int[] a,int[] b)方法可以判断int型数组a和数组b是否
相等(类似的方法还有double、char、byte型数组的equals()方法)。当数组a和数
组b相等时,该方法返回true;否则返回false。
比如,在编写标准化考试的程序时,将标准答案(多选题)如ABD存放在一
个数组里,代码如下:
char [] answer = {'A','B','D'};(也许某个开发者写成{'B','A','D'};)
考试者即用户提交的答案数组是:
char [] user = {'B','D','A'};
或
char [] user = {'B','A'};
那么,怎样使用equals()方法给用户判定成绩呢?换言之,在某些应用中,只要两
个数组长度一样,含有的数据也一样,就认为二者相等,而不要求两个数组的元
素按索引顺序依次相同。一个简单的办法就是把二者都排序,代码如下:
Arrays.sort(answer);
Arrays.sort(user);
然后再使用boolean equals(char []a,char[] b)方法,代码如下:
boolean isRight = Arrays.equals(answer,user);
得到一个值isRight,再根据isRight是true或false判断用户提交的数组和标准答案的
数组是否相等,然后决定给多少分。
2. 涉及的其他知识点
java.util包中的Random类以及for循环语句。
3. 进一步的尝试
从不连续的若干个数字中随机抽取若干个数。例如,从1、2、5、8、10、
14、23、30中随机抽取6个数字。
12 趣懂Java旋律,击破36个难点
3.3 程序运行效果与视频讲解
老师分别在一班和二班随机提问6名同学。主类是ExtractNumber。程序运行效
果如图3.2所示。
图3.2 点名与大奖的程序运行效果
3.4 阅读源代码
(1)GetRandomNumber.java的代码如下:
import java.util.Random; //负责得到随机数
import java.util.Arrays;
public class GetRandomNumber {
public static int [] getRandomNumber(int max,int amount) {
int [] result = new int[amount<max?amount:max];
//存放得到的amount随机数
int [] a = new int[max]; //存放max个整数
Random random = new Random();
for(int i = 0;i<a.length;i++){
//将1至max个数放入数组a
a[i] = i+1;
}
for(int i =0;i<amount;i++) { //得到amount个随机数
int index = random.nextInt(a.length);
//随机得到数组的一个索引值
result[i] = a[index];
int [] b = Arrays.copyOfRange(a,0,index);
//数组b存放的是a[0]至a[index-1]
int [] c = Arrays.copyOfRange(a,index+1,a.length); //数组复制
a = new int[b.length+c.length];
//新的数组a中去掉了抽到的数字
视频讲解
场景故事3 点名与大奖13
for(int k=0;k<a.length;k++) {
if(k<b.length)
a[k] = b[k];
else
a[k] = c[k-b.length];
}
}
return result;
}
}
(2)ExtractNumber.java的代码如下:
import java.util.Arrays;
public class ExtractNumber {
public static void main(String args[]) {
int [] a =GetRandomNumber.getRandomNumber(30,6);
System.out.println("一班被抽到的回答问题的学号:");
System.out.println(Arrays.toString(a));
int [] b =GetRandomNumber.getRandomNumber(33,6);
System.out.println("二班被抽到的回答问题的学号:");
System.out.println(Arrays.toString(b));
Arrays.sort(a);
Arrays.sort(b);
boolean isSame =Arrays.equals(a,b);
System.out.println("两个班抽取的学号相同吗?"+isSame);
}
}