1

At the moment I'm calling the method reader.nextInt() twice so it's only using the addNumber() method for every other value rather than each one.

How do I go about fixing this issue?

I've tried using a while loop containing (true) as well as the one printed below, both encounter the same issue.

I forgot to mention, I need the programme to print the sum of all integers entered. This is to be triggered by entering the value of -1. The -1 is meant to be excluded from the sum.

import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    NumberStatistics stats = new NumberStatistics();
    Scanner reader = new Scanner (System.in);

    System.out.println("Type numbers:");

    while (reader.nextInt() != -1)    {            
        stats.addNumber(reader.nextInt()); 
    }

    System.out.println("sum: " + stats.sum());

  }
}

public class NumberStatistics {

private int amountOfNumbers;
private int sum;

  public NumberStatistics() {
    amountOfNumbers = 0;
    sum = 0;
  }

  public void addNumber(int number) {
    this.amountOfNumbers++;
    this.sum += number;
  }

  public int amountOfNumbers() {
    return this.amountOfNumbers;
  }

  public int sum()    {
    return this.sum;
  }

  public double average() {

    if (this.sum() == 0) {
        return 0;
    } 
    else {
        return (double) this.sum / this.amountOfNumbers;
    }
  }
}

3 Answers3

2

The problem here is that the scanner will jump to the next token for each call of nexInt() that's why you get the following numbers, and skip the expected one.

So don't use nextInt() in your while condition, use hasNextInt() instead.

So your code would look like this:

int next;
while (reader.hasNextInt() && (next = reader.nextInt()) != -1){
    stats.addNumber(next);
}
cнŝdk
  • 28,676
  • 7
  • 47
  • 67
2

You are calling twice nextInt(), hence reading two nubers one after the other.

You can do what you want like this:

int num;
while ((num = reader.nextInt()) != -1)    {
    stats.addNumber(num);
}

This makes use of the fact that assignment expressions (this: num = reader.nextInt()) not only assigns the value to num, but aslo evaluate to the value being assigned, so that we can compare it with -1.

Turtle
  • 1,507
  • 13
  • 24
Sweeper
  • 145,870
  • 17
  • 129
  • 225
  • @DanielCutter If you think an answer answers your question, please consider accepting it by clicking on that checkmark! – Sweeper Aug 11 '17 at 14:10
  • @Sweeper You should add a short explanation about what was happening IMHO, that will be more clear if someone checks it! :D Get your upvote anyway, you were faster than me :( – Turtle Aug 11 '17 at 14:31
  • @Nathan I thought I explained well enough, with the `assignment expressions evaluate to the value being assigned` sentence. I don't know how I can explain better... – Sweeper Aug 11 '17 at 14:32
  • @Sweeper I meant precising what you mean with "assignment expression", in this case nextInt()`. – Turtle Aug 11 '17 at 14:45
  • @Nathan Is this better now? – Sweeper Aug 11 '17 at 14:46
  • @Sweeper Yes! I proposed the addition of a sentence in the start to clarify what I felt was missing, if you want to add it. – Turtle Aug 11 '17 at 14:50
1

When you call nextInt(), the pointer in the scanner parse the int, then goes to the next element. So basically, you have :

pointer
   |
   |
   12345     12346    12347

while (nextInt() ...) // pointer moves to next int

           pointer
             |
             |
   12345     12346    12347

stats.addNumber(reader.nextInt()); // Now the pointer is already at the next one

So you are reading them two by two. You can correct this by doing:

int a;
while ((a = reader.nextInt()) != -1)
    stats.addNumber(a);

This way, the Reader#nextInt method is only called once.

Turtle
  • 1,507
  • 13
  • 24