1

Please refer to following code which is related for mathematical tables practice. For all multiplication of numbers other than 15 * 9 it works properly but there is problem with 15 * 9 .

package com.test;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

public class Entry {

    static Scanner scanIn;
    static Random random;
    static List<String> list;
    static List<String> mistakeList;
    static File mistakeFile;

    static {
        scanIn = new Scanner(System.in);
        random = new Random();
        list = new ArrayList<String>();

    }

    /**
     * Main function to call the private methods.
     */
    public static void main(String[] args) throws IOException {
        mistakeFile = new File(args[0]);
        if(!mistakeFile.exists())
        {
            try {
                mistakeFile.createNewFile() ;
            } catch (IOException e) {           
                e.printStackTrace();
            }
        }
        mistakeList = getFileContent(mistakeFile);
        System.out.println("Please enter max limit .....");
        Integer maxLimit = Integer.parseInt(scanIn.nextLine());

        System.out.println("Please enter min limit .....");
        Integer minLimit = Integer.parseInt(scanIn.nextLine());

        System.out.println("Enter the number if iterations ..... ");
        Integer iterations = Integer.parseInt(scanIn.nextLine());

        executeTable(maxLimit, minLimit, iterations);
        scanIn.close();
        writeIntoFile();
    }
    /**
     * 
     * Multiplication logic which outputs two numbers, take input from user and 
     * matches it with result of multiplicaion.
     */
    private static void executeTable(Integer maxLimit, Integer minLimit,
            Integer iterations) {
        int skipCount = 0;
        for (int iTemp = 0; iTemp < iterations; iTemp++) {
            try
            {
            Integer num1 = getNextRandomInt(minLimit, maxLimit);
            Integer num2 = getNextRandomInt(2, 9);
            if (list.contains(num1 + "_X_" + num2) && skipCount < 10) {
                iTemp = iTemp - 1;
                skipCount++;
                continue;
            }
            skipCount = 0;
            System.out.println(num1 + " X " + num2 + " = ");
            Integer usrAnswer = Integer.parseInt(scanIn.nextLine());
            Integer answer = num1 * num2;
            if (usrAnswer != answer) {
                System.out.println("WRONG!! The correct answer is  " + num1
                        + " X " + num2 + " = " + answer);
                if(!mistakeList.contains(num1 + "_X_" + num2))
                {
                    mistakeList.add(num1 + "_X_" + num2);
                }
            } else {
                if(!list.contains(num1 + "_X_" + num2))
                {
                    list.add(num1 + "_X_" + num2);
                }
            }
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }

        }

    }

    /**
     * Gets next random number
     * 
     */
    private static Integer getNextRandomInt(Integer minLimit, Integer maxLimit) {
        Integer number = random.nextInt();
        if(maxLimit < minLimit)
        {
            maxLimit = maxLimit + minLimit ;
            minLimit = maxLimit - minLimit ;
            maxLimit = maxLimit - minLimit ;
        }

        number = (number % (maxLimit - minLimit + 1));
        if (number < 0) {
            number = -number;
        }
        number += minLimit;
        return number;
    }

    /**
     * Records commom mistake in file
     */
    private static void writeIntoFile() throws IOException 
    {
        String fileContent = "" ;
        for(String data : mistakeList)
        {
            fileContent = fileContent +data+ "\r\n" ;
        }
        try (FileWriter fw = new FileWriter(mistakeFile.getAbsoluteFile(), false);
                BufferedWriter bw = new BufferedWriter(fw)) {
            bw.write(fileContent);
            bw.close();
        }

    }

    /**
     *Returns file content.
     *
     */
    private static List<String> getFileContent(File file) {
        List<String> lst = new ArrayList<String>();
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {

            String sCurrentLine;

            while ((sCurrentLine = br.readLine()) != null) {
                lst.add(sCurrentLine);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return lst;
    }
}

The console output is as follows .

Please enter max limit .....
15

Please enter min limit .....
15

Enter the number if iterations ..... 
100

15 X 2 = 
30

15 X 8 = 
120

15 X 9 = 
135

WRONG!! The correct answer is  15 X 9 = 135

Though 135 proper input is provided the above program shows error for it. Dont know whats problem with 15 * 9

Adding more description.

The above program generates two random number within a limit and user has to enter the correct answer for it.Example.The above program displays two numbers like "15 X 8 =" and user has to enter 120. The above program works well for all other combinations other than "15 X 9 =". User enters 135 which is correct answer still the program shows it incorrect answer.

rajb
  • 71
  • 1
  • 1
  • 3
  • What is the exact error ? – Arnaud Jan 05 '16 at 10:00
  • Using `Scanner#nextLine` method after `Scanner#nextXX` methods will cause such problems. – TheLostMind Jan 05 '16 at 10:02
  • are you entring 15*9 in the command line? if so it's normal, he consider the input String "15 * 9" which is not castable to Integer. Can you provide us more details about the input, the output and the error, plz? – kayosoufiane Jan 05 '16 at 10:03
  • 1
    The above program generates two random number within a limit and user has to enter the correct answer for it.Example.The above program displays two numbers like "15 X 8 =" and user has to enter 120. The above program works well for all other combinations other than "15 X 9 =". User enters 135 which is correct answer still the program shows it incorrect answer. – rajb Jan 05 '16 at 10:13

2 Answers2

1

The problem is here:

if (usrAnswer != answer) {

You are comparing Integer objects, that must be done like so:

if (usrAnswer.equals(answer)) {

Comparison with != checks if the object instances are the same. The reason why it worked for smaller numbers is that instances are cached up to a certain limit.

A better solution in this case case would be to use the primitive int type:

int usrAnswer = Integer.parseInt(scanIn.nextLine());
int answer = num1 * num2;
if (usrAnswer != answer) {
Henry
  • 40,427
  • 6
  • 56
  • 72
1

That's because of comparing objects with ==. The problem is within these lines:

Integer usrAnswer = Integer.parseInt(scanIn.nextLine());
Integer answer = num1 * num2;
if (usrAnswer != answer)
  • Integer.parseInt(scanIn.nextLine()) returns int, then auto-box it into Integer using Integer.valueOf().
  • num1 * num2 will unbox both operands using num.intValue(), execute the multiplication which results in an int, and then auto-box it into Integer using Integer.valueOf().

In Integer class, the values [-128, 127] are cached, so Integer.valueOf(55) will return the same object every time, while Integer.valueOf(135) will return a new object every time.

  • In third line, you are comparing 2 Integer objects with reference comparsion ==. When the value of Integer is in the cache range, then both objects will be the same, otherwise they are different objects.

To solve this issue, I suggest that you change Integer to int:

int usrAnswer = Integer.parseInt(scanIn.nextLine());
int answer = num1 * num2;
if(usrAnswer != answer)

or compare the two Integer objects with .equals():

if(!usrAnswer.equals(answer))
Eng.Fouad
  • 107,075
  • 62
  • 298
  • 390