我正在尝试制作一个程序,它会向您询问数组中的随机问题。你回答它们,它会告诉你你是否正确。
我有一个问题数组:
String[] questions = {"Type A", "Type B", "Type C", "Type D", "Type E", "Type F", "Type G"};
然后我有一个答案数组。它们彼此对应,因此answers[0]
是questions[0]
String[] answerKey = {"A", "B", "C", "D", "E", "F", "G"};
int questionNum = 0; //Used as a counter for the questions.
这是我的代码尝试。
public void setUpQuestion() {
String[] answers = new String[4]; //An array of possible answers.
ArrayList<Integer> usedNumbers = new ArrayList<Integer>(); //An Arraylist of question positions.
ArrayList<Integer> usedQuestions = new ArrayList<Integer>(); //A copy of the usednumbers arraylist
for (int i = 0; i < answerKey.length; i++) //Add 0 through 6 to this arraylist, represents the questions
usedNumbers.add(i);
Collections.shuffle(usedNumbers); // Shuffle the arrayList into a random order
usedQuestions = usedNumbers; //Copy the array
for (int a = 0; a < answers.length; a++) { // This for loop should add random answers to the answers array
if (a == 0) {//For the first time around, add the correct answer into the array
answers[a] = answerKey[usedQuestions.get(questionNum)]; //answers[0] = the correct answer to the question
usedNumbers.remove(questionNum); //remove it from the copied array, so we don't accidentally use it twice
} else if (a != 0) { //For the rest of the spots, randomly pick answers that are wrong
answers[a] = answerKey[usedNumbers.get(0)];//pick a random answer that is next
usedNumbers.remove(0);//Remove it so it isnt used again
}
}
lblQuestion.setText(questions[usedQuestions.get(questionNum)]); // Set the label to the question
shuffleArray(answers);//shuffle the array of answers
btnA.setText(answers[0]); //set the button to one of the answers, etc;
btnB.setText(answers[1]);
btnC.setText(answers[2]);
btnD.setText(answers[3]);
}
希望我已经对它进行了彻底的评论,以便您知道代码在做什么
这似乎应该在理论上有效,但是,当我运行它时,会发生这种情况: 没有列出正确的答案。
如果有人能帮我弄清楚为什么这不起作用,我会非常感激。
谢谢!
编辑:
我尝试过一种可能效果更好的不同方法。我创建了一个Question对象,其参数为String question,String answer。
所以,我制作了一堆新的问题对象
public int questionNum = 0; //this is a global variable
Question a = new Question("Type A", "A");
Question b = new Question("Type B", "B");
Question c = new Question("Type C", "C");
Question d = new Question("Type D", "D");
Question e = new Question("Type E", "E");
Question[] questionBank = {a, b, c, d, e};
ArrayList<Question> questionArray = new ArrayList<Question>();
这是我对代码的新尝试:
for (int i = 0; i < questionBank.length; i++) questionArray.add(questionBank[i]);//Add all question objects to an arraylist
String[] answers = new String[4];//possible answers
Collections.shuffle(questionArray);//randomize thequestion array,
for (int a = 0; a < answers.length; a++) {
if (a == 0) {//First time around, add the correct answer to the array
answers[a] = questionArray.get(questionNum).getA();//getA() method gets the answer from the question array
} else if (a != 0) {
answers[a] = questionArray.get(a).getA();
questionArray.remove(a);
}
}
lblQuestion.setText(questionArray.get(questionNum).getQ()); //Gets the current question
btnA.setText(answers[0]);
btnB.setText(answers[1]);
btnC.setText(answers[2]);
btnD.setText(answers[3]); //set the answers on the buttons
questionArray.remove(questionNum);
答案 0 :(得分:0)
更改
usedQuestions = usedNumbers;
到
usedQuestions = new ArrayList<>(usedNumbers);
如何运作
观察以下示例:
Integer h = 3;
Integer j = h;
h++;
System.out.println(j);
输出是什么?你可能认为,它是3
。
h
的值为3。j
的值与h
相同。h
已更改。j
未被更改。j
是h
之前的值。果然,你写下这个:
ArrayList<Integer> usedNumbers = new ArrayList<Integer>();
ArrayList<Integer> usedQuestions = new ArrayList<Integer>();
for (int i = 0; i < 3; i++) // add 0, 1, 2
usedNumbers.add(i);
usedQuestions = usedNumbers;
usedNumbers.remove(0);
System.out.println(usedQuestions);
认为输出为[0, 1, 2]
。错误!让我们看看与第一种情况的区别。
usedNumbers
获得了值[0, 1, 2]
。usedQuestions
与usedNumbers
的价值相同? NOPE! usedQuestions
获得与usedNumbers
相同的参考。 (以下说明)usedNumbers
已更改。usedQuestions
已更改。usedQuestions
的更改值为[1, 2]
。在Java中,大多数对象都是引用类型。这意味着它所持有的变量是对值的引用(指向内存中地址的指针)。当你写usedQuestions = usedNumbers
时,你所做的就是给出&#34;箭头&#34;它指向列表[0, 1, 2]
到usedQuestions
。现在,当您更改列表(使用remove
)时,您更改了列表的值,但是包含对该列表的引用的每个变量都将提供相同的修改列表。
第一个示例按预期工作,因为int
是原始类型,其中变量包含&#34; real&#34;值,而不是指向它的指针。在这种情况下,更改数字(使用++
)实际上更改了数字的值,但所有其他数字保持不变。
这与浅拷贝 vs 深拷贝密切相关。关于它的网站上有更多的问题,而不是我关心的链接,所以只有谷歌它和你得到的东西比你讨价还价的要多。简短的解释是浅拷贝只复制你所做的参考,而深拷贝使得#34;真正的&#34;价值的副本。 A&#34;真实&#34;复制意味着
行usedQuestions = new ArrayList<>(usedNumbers);
基本上会对列表进行深层复制(仅因为它是Integer
的列表),而usedQuestions = usedNumbers
是浅拷贝。
我在这里没有提到很多细节,也不是技术上的准确,但我试图简单地解释一个微妙而重要的话题。
如果您理解这一点,您可能已经理解了这一行
ArrayList<Integer> usedQuestions = new ArrayList<Integer>();
可以
ArrayList<Integer> usedQuestions;
原因是您不需要在代码中此时初始化列表,因为稍后将使用new ArrayList<>(usedNumbers)
对其进行初始化。具体来说,在你的原始代码中,你扔掉了#34;
ArrayList<Integer> usedQuestions = new ArrayList<Integer>();
当你给usedQuestions
指向
ArrayList<Integer> usedNumbers = new ArrayList<Integer>();