试图从数组中选择随机问题,并在单独的数组中找到答案?

时间:2015-12-13 00:37:16

标签: java arrays

我正在尝试制作一个程序,它会向您询问数组中的随机问题。你回答它们,它会告诉你你是否正确。

我有一个问题数组:

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]);

}

希望我已经对它进行了彻底的评论,以便您知道代码在做什么

这似乎应该在理论上有效,但是,当我运行它时,会发生这种情况: There is no correct answer listed 没有列出正确的答案。

如果有人能帮我弄清楚为什么这不起作用,我会非常感激。

谢谢!

编辑:

我尝试过一种可能效果更好的不同方法。我创建了一个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);

1 个答案:

答案 0 :(得分:0)

更改

usedQuestions = usedNumbers;

usedQuestions = new ArrayList<>(usedNumbers);

如何运作

观察以下示例:

Integer h = 3;
Integer j = h;
h++;
System.out.println(j);

输出是什么?你可能认为,它是3

  1. h的值为3。
  2. j的值与h相同。
  3. h已更改。
  4. j未被更改。
  5. jh之前的值。
  6. 果然,你写下这个:

    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]。错误!让我们看看与第一种情况的区别。

    1. usedNumbers获得了值[0, 1, 2]
    2. usedQuestionsusedNumbers的价值相同? NOPE! usedQuestions获得与usedNumbers相同的参考。 (以下说明)
    3. usedNumbers已更改。
    4. usedQuestions 更改。
    5. usedQuestions的更改值为[1, 2]
    6. 在Java中,大多数对象都是引用类型。这意味着它所持有的变量是对值的引用(指向内存中地址的指针)。当你写usedQuestions = usedNumbers时,你所做的就是给出&#34;箭头&#34;它指向列表[0, 1, 2]usedQuestions。现在,当您更改列表(使用remove)时,您更改了列表的值,但是包含对该列表的引用的每个变量都将提供相同的修改列表

      第一个示例按预期工作,因为int原始类型,其中变量包含&#34; real&#34;值,而不是指向它的指针。在这种情况下,更改数字(使用++)实际上更改了数字的值,但所有其他数字保持不变。

      这与浅拷贝 vs 深拷贝密切相关。关于它的网站上有更多的问题,而不是我关心的链接,所以只有谷歌它和你得到的东西比你讨价还价的要多。简短的解释是浅拷贝只复制你所做的参考,而深拷贝使得#34;真正的&#34;价值的副本。 A&#34;真实&#34;复制意味着

      1. 对一个副本的更改不会影响另一个副本。
      2. 您正在使用两倍的内存,因为您将相同的数据保存在两个不同的地址中。
      3. 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>();