作为练习,我将7个整数(每个整数介于1和39之间)添加到ArrayList,然后使用for循环打印出整数。我似乎得到了预期的输出(例如,彩票号码:3 5 10 14 15 27 37)。但是我的代码没有通过自动化测试。该测试给出以下错误消息:“在drawNumbers调用之后,数字列表的大小应为7!预期:< 7>但是:< 14>”
我想也许我将7个整数添加为14个单独的数字而不是7个双位整数。但是,我对此非常不确定。能够深入了解出了什么问题会很棒。
主程序:
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
LotteryNumbers lotteryNumbers = new LotteryNumbers();
ArrayList<Integer> numbers = lotteryNumbers.numbers();
System.out.println("Lottery numbers:");
for(int number : numbers) {
System.out.print(number + " ");
}
System.out.println("");
}
}
和班级:
import java.util.ArrayList;
import java.util.Random;
public class LotteryNumbers {
private final ArrayList<Integer> numbers;
private final Random random;
private int number;
public LotteryNumbers() {
this.numbers = new ArrayList<Integer>();
this.random = new Random();
this.drawNumbers();
}
public ArrayList<Integer> numbers() {
return this.numbers;
}
public void drawNumbers() {
int i = 0;
while(i < 7) {
while(true) {
this.number = random.nextInt(39)+1;
if(!containsNumber(number)) {
break;
}
}
this.numbers.add(this.number);
i++;
}
}
public boolean containsNumber(int number) {
return numbers.contains(number);
}
}
以下是测试代码:
import fi.helsinki.cs.tmc.edutestutils.Points;
import static org.junit.Assert.*;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
@Points("82")
public class LotteryNumbersTest {
public ArrayList<Integer> test() {
LotteryNumbers lottoRivi;
ArrayList<Integer> numerot;
try {
lottoRivi = new LotteryNumbers();
numerot = lottoRivi.numbers();
} catch (Throwable t) {
fail("Something went wrong when creating a new LotteryNumbers object! More info: " + t);
return null; // tyhmä java
}
assertEquals("The size of number list should be seven!", 7, numerot.size());
Set<Integer> jaljellaOlevatNumerot = new HashSet<Integer>();
for (int i = 1; i <= 39; i++) {
jaljellaOlevatNumerot.add(i);
}
Set<Integer> arvotutNumerot = new HashSet<Integer>();
for (int i : numerot) {
assertTrue("A lottery number should belong to range 1-39. However, you returned number: " + i,
(i >= 1 && i <= 39));
assertTrue("The method containsNumber() returns false, despite the drawn number was among the list of drawn numbers: " + i,
lottoRivi.containsNumber(i));
assertTrue("The numbers returned contain multiple times a number: " + i,
arvotutNumerot.add(i));
jaljellaOlevatNumerot.remove(i);
}
for (int i : jaljellaOlevatNumerot) {
assertFalse("The method containsNumber() returns true, despite the drawn number was not among the list of drawn numbers: " + i,
lottoRivi.containsNumber(i));
}
return numerot;
}
@Test
public void testOne() {
test();
}
@Test
public void testDrawNumbersCallRemovesOldNumbersAndDrawsNew() {
LotteryNumbers lottoRivi;
ArrayList<Integer> numerot;
try {
lottoRivi = new LotteryNumbers();
numerot = lottoRivi.numbers();
} catch (Throwable t) {
fail("Something went wrong when creating a new LotteryNumbers object! More info: " + t);
return;
}
String numerotString = numerot.toString();
assertEquals("The size of number list should be seven!", 7, numerot.size());
lottoRivi.drawNumbers();
assertEquals("The size of number list should be seven after drawNumbers call!", 7, lottoRivi.numbers().size());
assertFalse("New numbers should have been drawn with drawNumbers call! Numbers were " + numerotString,numerotString.equals(lottoRivi.numbers().toString()));
}
@Test
public void testMany() {
int[] arr = new int[40];
for (int i = 0; i < 200; i++) {
for (int x : test()) {
arr[x]++;
}
}
int montako=0;
for (int i = 1; i <= 39; i++) {
if (arr[i]>0) {
montako++;
}
}
assertEquals("200 lottery draws produced only " + montako +
" different values! Not very random!", 39, montako);
}
}
实现了@Eran的建议,将numbers.clear()作为drawNumbers()方法的第一个语句,代码给出了正确的输出并通过了测试。这使我能够将我的代码提交给课程提供者(TestMyCode MOOC),然后查看我在下面粘贴的模型答案:
import java.util.ArrayList;
import java.util.Random;
public class LotteryNumbers {
private ArrayList<Integer> numbers;
public LotteryNumbers() {
// Draw numbers as LotteryNumbers is created
this.drawNumbers();
}
public ArrayList<Integer> numbers() {
return this.numbers;
}
public void drawNumbers() {
// We'll format a list for the numbers
this.numbers = new ArrayList<Integer>();
// Write the number drawing here using the method containsNumber()
Random random = new Random();
while (this.numbers.size() < 7) {
int newNumber = random.nextInt(39) + 1;
boolean alreadyDrawn = this.containsNumber(newNumber);
// we add the number only if it is not already among the drawn numbers
if (!alreadyDrawn) {
this.numbers.add(newNumber);
}
}
}
public boolean containsNumber(int number) {
// Test here if the number is already in the drawn numbers
for (int n : this.numbers) {
if (n == number) {
return true;
}
}
return false;
}
}
答案 0 :(得分:3)
您正在drawNumbers()
构造函数中调用LotteryNumbers
,因此在创建LotteryNumbers
实例后,它已包含7个数字。
根据自动化测试的消息 - The size of number list should be seven after drawNumbers call! expected:<7> but was:<14>
- 它可能会再次调用drawNumbers()
,这会在列表中再添加7个数字。因此,您最终得到14个数字。
您应该从构造函数中删除对drawNumbers()
的调用。
编辑:
看到测试方法 - testDrawNumbersCallRemovesOldNumbersAndDrawsNew()
- 您后来添加到问题中,它希望列表在调用drawNumbers()
之前和之后有7个数字。因此,您应该在构造函数中保留drawNumbers()
,但要清除drawNumbers()
开头的列表(通过调用numbers.clear()
)。
答案 1 :(得分:3)
这种情况下的修复很简单,只需在clear()
开头的ArrayList上调用drawNumbers()
:
public void drawNumbers() {
numbers.clear();
int i = 0;
while(i < 7) {
while(true) {
this.number = random.nextInt(39)+1;
if(!containsNumber(number)) {
break;
}
}
this.numbers.add(this.number);
i++;
}
}
此外,您应该考虑仅提供ArrayList的副本,因此对ArrayList的修改不会反映在您的类中,反之亦然。
答案 2 :(得分:2)
正如Eran所说,问题可能是测试用例明确调用了drawNumbers()
,从而在numbers
列表中添加了7个元素。
考虑什么&#34; drawNumbers&#34;应该这样做:它应该添加更多数字,还是应该随机抽取替换数字?
由于您没有清除数字列表,如果我drawNumbers()
被调用5次,代码将进入无限循环!
答案 3 :(得分:1)
绝对不要将整数作为单个数字添加。
在这种情况下,drawNumbers()方法执行两次。你在构造函数中调用它,然后它会在测试用例中调用一次,这就是为什么计数为14。
在构造函数中注释drawNumbers()并将其添加到main方法
public LotteryNumbers() {
this.numbers = new ArrayList<Integer>();
this.random = new Random();
//this.drawNumbers();
}
public static void main(String[] args) {
LotteryNumbers lotteryNumbers = new LotteryNumbers();
lotteryNumbers.drawNumbers();
ArrayList<Integer> numbers = lotteryNumbers.numbers();
System.out.println("Lottery numbers:");
for(int number : numbers) {
System.out.print(number + " ");
}
System.out.println(numbers.size());
}
编辑:看到测试用例后,上面的答案是错误的。您必须将clear()添加到上面其他人提到的方法