Bordies
Bordies

Reputation: 21

Why does Java 'break' statement not working?

Here is my code:

public static void main(String args[]) throws Exception {
    
    int length; 
    Scanner input = new Scanner (System.in);
    Scanner scanner = new Scanner(System.in);
    
    System.out.println(" How many dates would you like to include for the expiration dates notification? ");
    length=scanner.nextInt();  
    String[] dates = new String[length]; 
    System.out.println(" input date, formatting is hh:mm:ss");
    for(int i=0; i<length; i++)  
    {
    dates[i]=scanner.next(); 
    }
    
    System.out.println("== DATE LIST =="); 
    for (int i=0; i<length; i++)   
    {  
    System.out.println(dates[i]); 
    }  
    
    int loopcount;
            System.out.print("Please enter how much notification you would like to put in: ");
            loopcount = input.nextInt();
            
    
    System.out.println("== EXPIRE LIST ==\n"); 
    while (true) { 
        for (String z : dates) { 
            Thread.sleep(50); 

            LocalDateTime now = LocalDateTime.now();
            Date convertednow = Date.from(now.atZone(ZoneId.systemDefault()).toInstant()); 
            SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm:ss"); 
            String strnow = dateFormat.format(convertednow); 

            if (strnow.equals(z)) { 
                System.out.print(z+" has expired\n"); 
               
                
                
            
            int i = 0;                
            while(i < loopcount) { 
                System.out.println("Notification stopped");
                i++;
                if (i == 3) {
                    break;
                }
                
            }
            
            
            
        }
    }
   }
}

I am new to Java. Sorry if I made a lot of mistakes. What I was trying to do is make a timer that will notify the user when the certain time has reached. The user will input the timer via Scanner. My plan is when all of the timers that I input earlier has been notified, it will stop and give the message "Notification Stop" in the last line of the output. The problem that I am currently facing right now is whenever I am trying to stop the loop by using break statement. It just won't work and it will keep stuck in an infinite loop until I force it to stop.

Thank you for reading this.

Upvotes: 1

Views: 623

Answers (2)

Andreas
Andreas

Reputation: 159114

The break statement exits the inner-most loop, i.e. the while(i < loopcount) loop, not the middle for (String z : dates) loop or the outer while (true) loop.

If you want break to exit the outer loop, you can do it by using a label:

System.out.println("== EXPIRE LIST ==\n");
MAIN: while (true) { // <== Added label 'MAIN'
    for (String z : dates) {
        Thread.sleep(50);

        . . .

        int i = 0;
        while(i < loopcount) {
            System.out.println("Notification stopped");
            i++;
            if (i == 3) {
                break MAIN; // <== Exit loop labeled 'MAIN'
            }
        }
    }
}

Note: Some people highly discourage the use of labels, because it behaves similar to goto statements in other languages, and is considered bad for the code structure.

You can also use a return statement, if there is no code after the while (true) loop. Somewhat same argument against that (code structure).

Alternative is to use a boolean variable.

System.out.println("== EXPIRE LIST ==\n");
boolean done = false;
while (! done) { // <== Exit outer loop when "done"
    for (String z : dates) {
        Thread.sleep(50);

        . . .

        int i = 0;
        while(i < loopcount) {
            System.out.println("Notification stopped");
            i++;
            if (i == 3) {
                done = true;
                break; // <== Exit inner while-loop
            }
        }
        if (done)
            break; // <== Exit for-loop
    }
}

Upvotes: 3

WJS
WJS

Reputation: 40044

You can do it by putting a label on the outer while and breaking on that label. A break normally only applies to to the immediate loop in which it is executed. So the inner break only breaks out of the inner while loop.

Another option is to use setable boolean in the loops and then conditionally set them to false to control when they will stop.

System.out.println("== EXPIRE LIST ==\n"); 
outer:
while (true) { 
    for (String z : dates) { 
        Thread.sleep(50); 
        LocalDateTime now = LocalDateTime.now();
        Date convertednow = 
             Date.from(now.atZone(ZoneId.systemDefault()).toInstant()); 
        SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm:ss"); 
        String strnow = dateFormat.format(convertednow); 
        if (strnow.equals(z)) { 
            System.out.print(z+" has expired\n");         
        
        int i = 0;                
        while(i < loopcount) { 
            System.out.println("Notification stopped");
            i++;
            if (i == 3) {
                break outer;
            }         
        }      
    }
}

Upvotes: 1

Related Questions