A is for Ambition A is for Ambition - 4 months ago 6
Java Question

Why does the if-block not run for the final case?

Consider the following code, which counts how many of each element an array has:

public static void getCounts(int[] list) {
int current = list[0];
int count = 0;
for (int i = 0; i < list.length; i++, count++) {
if (list[i] > current) {
System.out.println(current + " occurs " + count + timeOrTimes(count));
current = list[i];
count = 0;
}
}
System.out.println(current + " occurs " + count + timeOrTimes(count));
}


For this question, please assume
list
is sorted in ascending order. If
list
is
[1, 1, 2, 3, 4, 4]
, for example, the output is:

1 occurs 2 times
2 occurs 1 time
3 occurs 1 time
4 occurs 2 times


Now, if I get rid of the
println
that comes after the
for
-loop, i.e.

public static void getCounts(int[] list) {
int current = list[0];
int count = 0;
for (int i = 0; i < list.length; i++, count++) {
if (list[i] > current) {
System.out.println(current + " occurs " + count + timeOrTimes(count));
current = list[i];
count = 0;
}
}
// System.out.println(current + " occurs " + count + timeOrTimes(count));
}


Then using the same example input, the output becomes:

1 occurs 2 times
2 occurs 1 time
3 occurs 1 time


In other words, the
if
block doesn't execute if
list[i]
is the maximum value of the array. Why is this the case? For the example above, the index of the first
4
is
i = 4
, and
list[4] > 3
, so the conditional statement is met, but it still won't execute.

How can I adjust the code so that the
if
block will run for all cases?

Thanks

Answer

The final println is necessary because you are triggering your print statement on a change in the value of list[i] and printing the result for the previous value. At the end of the program there's no last "change" to be detected, so you need to handle the last case separately.

This (the need for a final operation after the loop) is a standard coding pattern that occurs any time a variable change in a sequence triggers an operation at the end of a batch. One way of thinking about it is that there's a virtual value, one past the end of your array, that is always larger than any possible previous value and signals the end of data. There's no need to test for it or actually implement it, but you still have to code the operation (in your case a println).

The operation could be much more complex, in which case you'd encapsulate it in a method to avoid code duplication. Your code could benefit slightly from encapsulating the println in a method outputCount(int value, int count) .

Comments