Search code examples
javawhile-loopbreak

break statement does not stop executing while loop Immediately in java


I am trying to run a program that asks the user to list some values. These values will then be stored in a list and once the user types 0 the loop should terminate and the program should find the smallest and largest values the user had inputted.

the code where I initialise the loop to store the values is below:

    public static void main(String[] Args){
        Scanner in = new Scanner(System.in);
        ArrayList<Integer> list = new ArrayList<>();
        System.out.println("This program finds the largest and smallest numbers");
        while(true) {
            System.out.println("?");
            int value = in.nextInt();
            if(value == 0) {break;}
            list.add(value);
        }
        System.out.println("smallest:" + findSmallest(list));
        System.out.println("largest:" + findLargest(list));
    }


Instead of the break statement exiting the while loop immediately before adding the input 0 to the list, it triggers only after the entire while loop had finished. For example If i type 5,3 and 0 I should get:

smallest:3 largest:5

but instead i get:

smallest:0 largest:5

Why is this happenning and how can I solve it?

For reference here is the entire code:

package Programs;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class FindRange {
    /* sentinel value for exiting the program*/
    private static final int sentinel = 0;
    
    
    public static void main(String[] Args){
        Scanner in = new Scanner(System.in);
        ArrayList<Integer> list = new ArrayList<>();
        System.out.println("This program finds the largest and smallest numbers");
        while(true) {
            System.out.println("?");
            int value = in.nextInt();
            if(value == 0) {break;}
            list.add(value);
        }
        System.out.println("smallest:" + findSmallest(list));
        System.out.println("largest:" + findLargest(list));
    }
    
    /* 
     * Precondition: We must receive a list of type ArrayList containing
     * int values provided by the user
     * PostConditions: Provides the smallest value in the list 
     * */
    private static int findSmallest(ArrayList<Integer> list){
        int smallest = list.get(0);
        for (int i=0;i<list.size()-1;i++) {
            if (i<smallest) {
                smallest = i;
            }
        }
        return smallest;
                }
    
    /* 
     * Precondition: We must receive a list of type ArrayList containing
     * int values provided by the user
     * PostConditions: Provides the Largest value in the list 
     * 
     * Error with code: Some reason break statement on main doesn't stop the execution of the loop straight away
     * resulting in the sentinel 0 being stored in the list. 
     * */
    private static int findLargest(ArrayList<Integer> list){
        int Largest = list.get(0);
        for (int i=0;i<list.size()-1;i++) {
            if (i>Largest) {
                Largest = i;
            }
        }
        return Largest;
                }
    

}
    

Solution

  • Your break is working correctly. The issue is in the implementations of findSmallest and findLargest. For instance, you have:

    private static int findSmallest(ArrayList<Integer> list){
        int smallest = list.get(0);
        for (int i=0;i<list.size()-1;i++) {
            if (i<smallest) {
                smallest = i;
            }
        }
        return smallest;
    }
    

    Here, i is the index, not the value at that index. Also, your loop's condition is wrong. It's already exclusive, since you are using <, meaning you should not be subtracting one from the size of the list.

    You want something like:

    private static int findSmallest(ArrayList<Integer> list){
        int smallest = list.get(0);
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) < smallest) {
                smallest = list.get(i);
            }
        }
        return smallest;
    }
    

    Or you can use a for-each loop:

    private static int findSmallest(ArrayList<Integer> list){
        int smallest = list.get(0);
        for (Integer value : list) {
            if (value < smallest) {
                smallest = value;
            }
        }
        return smallest;
    }
    

    Similar changes need to be made for findLargest.