Kotlin Break and Continue Statements

The Kotlin break continue statements are structural jump expressions that modify the normal flow of loop execution. While break terminates the loop entirely, continue skips the current iteration and moves to the next one. These statements work with all types of loops in Kotlin, including for loops, while loops, and do-while loops.

Understanding the Break Statement in Kotlin

The Kotlin break statement immediately terminates the nearest enclosing loop when a specific condition is met. When the program encounters a break statement, it exits the loop and continues executing the code that follows the loop block.

Break Statement Syntax

The basic syntax for using break in different loop types:

// Using break in for loop  
for (element in collection) {  
    if (condition) {  
        break  
    }  
    // Other code  
}  
  
// Using break in while loop    
while (condition) {  
    if (testCondition) {  
        break  
    }  
    // Other code  
}  
  
// Using break in do-while loop  
do {  
    if (testCondition) {  
        break    
    }  
    // Other code  
} while (condition)  

Simple Break Example

Here’s a practical example demonstrating how break works in a for loop:

fun searchInNumbers() {  
    val numbers = listOf(10, 25, 3, 40, 15, 8)  
      
    for (number in numbers) {  
        println("Checking number: $number")  
        if (number > 30) {  
            println("Found number greater than 30: $number")  
            break  // Exit the loop immediately  
        }  
    }  
    println("Search completed")  
}  

In this example, the loop stops as soon as it finds a number greater than 30, demonstrating how break prevents unnecessary iterations.

Mastering the Continue Statement in Kotlin

The Kotlin continue statement skips the remaining code in the current iteration and jumps to the next iteration of the loop. Unlike break, continue doesn’t terminate the entire loop but simply bypasses the current cycle.

Continue Statement Syntax

The continue statement follows this pattern in different loops:

// Using continue in for loop  
for (element in collection) {  
    if (skipCondition) {  
        continue  
    }  
    // This code executes only if skipCondition is false  
}  
  
// Using continue in while loop  
while (condition) {  
    if (skipCondition) {  
        continue  
    }  
    // Process elements  
}  

Practical Continue Example

Let’s see how continue works in filtering operations:

fun processEvenNumbers() {  
    val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)  
    var sum = 0  
      
    for (number in numbers) {  
        if (number % 2 != 0) {  
            continue  // Skip odd numbers  
        }  
        sum += number  
        println("Added even number: $number, Current sum: $sum")  
    }  
    println("Final sum of even numbers: $sum")  
}  

This example demonstrates how continue helps process only specific elements while skipping others based on conditions.

Advanced Labeling Techniques with Break and Continue

Kotlin break continue statements become even more powerful when combined with labels. Labels allow you to control exactly which loop to break or continue, especially useful in nested loop scenarios.

Understanding Kotlin Labels

A label in Kotlin consists of an identifier followed by the @ symbol. You can label any expression and reference it later with break or continue statements.

labelName@ for (element in collection) {  
    // Loop body  
}  

Labeled Break Examples

Here’s how labeled break works with nested loops:

fun demonstrateLabeledBreak() {  
    outerLoop@ for (i in 1..5) {  
        innerLoop@ for (j in 1..5) {  
            println("Processing: i=$i, j=$j")  
              
            if (i == 3 && j == 2) {  
                println("Breaking outer loop at i=3, j=2")  
                break@outerLoop  // Breaks the outer loop  
            }  
              
            if (j == 4) {  
                println("Breaking inner loop at j=4")  
                break@innerLoop  // Breaks only the inner loop  
            }  
        }  
        println("Completed inner loop for i=$i")  
    }  
    println("Program completed")  
}  

Labeled Continue Examples

Labeled continue provides precise control over which loop iteration to skip:

fun demonstrateLabeledContinue() {  
    outerLoop@ for (i in 1..4) {  
        println("Starting outer loop iteration: $i")  
          
        innerLoop@ for (j in 1..4) {  
            if (i == 2 && j == 2) {  
                println("Skipping outer loop iteration at i=2, j=2")  
                continue@outerLoop  // Skip to next outer loop iteration  
            }  
              
            if (j == 3) {  
                println("Skipping inner loop iteration at j=3")  
                continue@innerLoop  // Skip to next inner loop iteration  
            }  
              
            println("Processing: i=$i, j=$j")  
        }  
        println("Completed inner loop for i=$i")  
    }  
}  

Working with Break and Continue in Different Loop Types

Break and Continue in While Loops

While loops often use break and continue for user input validation and processing:

fun userInputProcessor() {  
    var userInput: String?  
    var validInputCount = 0  
      
    while (validInputCount < 3) {  
        print("Enter a positive number (or 'quit' to exit): ")  
        userInput = readLine()  
          
        if (userInput == "quit") {  
            println("Exiting program...")  
            break  // Exit the while loop  
        }  
          
        val number = userInput?.toIntOrNull()  
        if (number == null || number <= 0) {  
            println("Invalid input. Please try again.")  
            continue  // Skip to next iteration  
        }  
          
        validInputCount++  
        println("Valid input #$validInputCount: $number")  
    }  
      
    if (validInputCount == 3) {  
        println("Successfully collected 3 valid inputs!")  
    }  
}  

Break and Continue in Do-While Loops

Do-while loops guarantee at least one execution before checking conditions:

fun menuDrivenProgram() {  
    var choice: String?  
      
    do {  
        println("\n=== Menu ===")  
        println("1. Option A")  
        println("2. Option B")   
        println("3. Exit")  
        print("Enter your choice: ")  
          
        choice = readLine()  
          
        when (choice) {  
            "1" -> {  
                println("Executing Option A...")  
                // Some processing here  
                continue  // Go back to menu  
            }  
            "2" -> {  
                println("Executing Option B...")  
                // Some processing here  
                continue  // Go back to menu    
            }  
            "3" -> {  
                println("Goodbye!")  
                break  // Exit the loop  
            }  
            else -> {  
                println("Invalid choice. Please try again.")  
                continue  // Show menu again  
            }  
        }  
    } while (true)  
}  

Real-World Applications and Use Cases

Data Processing with Break and Continue

Here’s a practical example for processing student grades:

data class Student(val name: String, val grade: Int, val isActive: Boolean)  
  
fun processStudentGrades() {  
    val students = listOf(  
        Student("Alice", 85, true),  
        Student("Bob", 45, false),  
        Student("Charlie", 92, true),  
        Student("Diana", 78, true),  
        Student("Eve", 35, true),  
        Student("Frank", 88, false)  
    )  
      
    var totalGrades = 0  
    var activeStudentCount = 0  
    val passingGrade = 50  
      
    studentLoop@ for (student in students) {  
        // Skip inactive students  
        if (!student.isActive) {  
            println("Skipping inactive student: ${student.name}")  
            continue@studentLoop  
        }  
          
        // Stop if we find a failing active student  
        if (student.grade < passingGrade) {  
            println("Found failing student: ${student.name} with grade ${student.grade}")  
            println("Stopping grade calculation for review")  
            break@studentLoop  
        }  
          
        totalGrades += student.grade  
        activeStudentCount++  
        println("Added ${student.name}'s grade: ${student.grade}")  
    }  
      
    if (activeStudentCount > 0) {  
        val averageGrade = totalGrades.toDouble() / activeStudentCount  
        println("Average grade of processed active students: ${"%.2f".format(averageGrade)}")  
    }  
}  

File Processing Example

fun processLogFiles() {  
    val logEntries = listOf(  
        "INFO: Application started",  
        "DEBUG: Loading configuration",   
        "ERROR: Database connection failed",  
        "WARN: Retrying connection",  
        "INFO: Connection restored",  
        "FATAL: Critical system failure",  
        "INFO: System recovering"  
    )  
      
    var errorCount = 0  
    val maxErrors = 2  
      
    logProcessing@ for ((index, entry) in logEntries.withIndex()) {  
        println("Processing log entry ${index + 1}: $entry")  
          
        // Skip debug entries  
        if (entry.startsWith("DEBUG")) {  
            println("Skipping debug entry")  
            continue@logProcessing  
        }  
          
        // Count errors  
        if (entry.startsWith("ERROR") || entry.startsWith("FATAL")) {  
            errorCount++  
            println("Error detected. Total errors: $errorCount")  
              
            // Stop processing if too many errors  
            if (errorCount >= maxErrors) {  
                println("Maximum error threshold reached. Stopping log processing.")  
                break@logProcessing  
            }  
        }  
          
        // Process other entries  
        if (entry.startsWith("INFO") || entry.startsWith("WARN")) {  
            println("Normal log entry processed")  
        }  
    }  
      
    println("Log processing completed. Total errors found: $errorCount")  
}  

Break and Continue in Functional Programming

While traditional break and continue don’t work with functional methods like forEach, Kotlin provides alternatives using labeled returns:

Simulating Continue with forEach

fun functionalContinueExample() {  
    val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)  
    var sum = 0  
      
    numbers.forEach { number ->  
        if (number % 2 == 0) {  
            return@forEach  // Simulates continue - skip even numbers  
        }  
        sum += number  
        println("Added odd number: $number")  
    }  
      
    println("Sum of odd numbers: $sum")  
}  

Simulating Break with forEach

fun functionalBreakExample() {  
    val items = listOf("apple", "banana", "cherry", "date", "elderberry")  
      
    run breakLoop@ {  
        items.forEach { item ->  
            println("Processing: $item")  
            if (item.startsWith("d")) {  
                println("Found item starting with 'd': $item")  
                return@breakLoop  // Simulates break  
            }  
            println("Processed: $item")  
        }  
    }  
      
    println("Processing completed")  
}  

Error Handling with Break and Continue

Kotlin break continue statements work well with error handling patterns:

fun robustDataProcessor() {  
    val dataItems = listOf("123", "abc", "456", "def", "789", "", "101112")  
    var successfulItems = 0  
    var totalValue = 0  
      
    dataProcessing@ for ((index, item) in dataItems.withIndex()) {  
        println("Processing item ${index + 1}: '$item'")  
          
        try {  
            // Skip empty strings  
            if (item.isEmpty()) {  
                println("Skipping empty item")  
                continue@dataProcessing  
            }  
              
            val numericValue = item.toInt()  
              
            // Stop if we encounter a number that's too large  
            if (numericValue > 10000) {  
                println("Number too large: $numericValue. Stopping processing.")  
                break@dataProcessing  
            }  
              
            totalValue += numericValue  
            successfulItems++  
            println("Successfully processed: $numericValue")  
              
        } catch (e: NumberFormatException) {  
            println("Skipping non-numeric item: '$item'")  
            continue@dataProcessing  
        }  
    }  
      
    println("Processing summary:")  
    println("- Successfully processed items: $successfulItems")  
    println("- Total value: $totalValue")  
    if (successfulItems > 0) {  
        println("- Average value: ${totalValue.toDouble() / successfulItems}")  
    }  
}  

Complete Working Examples

Here’s a comprehensive example that demonstrates all concepts covered:

// Import statements  
import kotlin.random.Random  
  
// Data classes  
data class Product(val id: Int, val name: String, val price: Double, val inStock: Boolean)  
data class Order(val productId: Int, val quantity: Int)  
  
fun main() {  
    // Sample data  
    val products = listOf(  
        Product(1, "Laptop", 999.99, true),  
        Product(2, "Mouse", 25.50, false),  
        Product(3, "Keyboard", 79.99, true),  
        Product(4, "Monitor", 299.99, true),  
        Product(5, "Webcam", 89.99, false),  
        Product(6, "Speakers", 129.99, true)  
    )  
      
    val orders = listOf(  
        Order(1, 2),  
        Order(2, 1),  
        Order(3, 3),  
        Order(4, 1),  
        Order(5, 2),  
        Order(6, 1)  
    )  
      
    println("=== E-commerce Order Processing System ===\n")  
      
    // Process orders with break and continue  
    processOrders(products, orders)  
      
    println("\n=== Inventory Management ===\n")  
      
    // Inventory check with labeled loops  
    performInventoryCheck(products)  
      
    println("\n=== Price Analysis ===\n")  
      
    // Price analysis with functional approach  
    analyzePrices(products)  
}  
  
fun processOrders(products: List<Product>, orders: List<Order>) {  
    var totalRevenue = 0.0  
    var processedOrders = 0  
    val maxOrdersToProcess = 4  
      
    println("Processing customer orders...")  
      
    orderProcessing@ for ((orderIndex, order) in orders.withIndex()) {  
        println("\nProcessing order ${orderIndex + 1}: Product ID ${order.productId}, Quantity ${order.quantity}")  
          
        // Stop processing if we've reached the maximum  
        if (processedOrders >= maxOrdersToProcess) {  
            println("Reached maximum order processing limit ($maxOrdersToProcess)")  
            break@orderProcessing  
        }  
          
        // Find the product  
        val product = products.find { it.id == order.productId }  
          
        if (product == null) {  
            println("Product not found for ID ${order.productId}. Skipping order.")  
            continue@orderProcessing  
        }  
          
        // Check if product is in stock  
        if (!product.inStock) {  
            println("Product '${product.name}' is out of stock. Skipping order.")  
            continue@orderProcessing  
        }  
          
        // Process the order  
        val orderTotal = product.price * order.quantity  
        totalRevenue += orderTotal  
        processedOrders++  
          
        println("✓ Order processed successfully!")  
        println("  Product: ${product.name}")  
        println("  Unit Price: $${product.price}")  
        println("  Quantity: ${order.quantity}")  
        println("  Order Total: $${String.format("%.2f", orderTotal)}")  
    }  
      
    println("\n--- Order Processing Summary ---")  
    println("Total orders processed: $processedOrders")  
    println("Total revenue generated: $${String.format("%.2f", totalRevenue)}")  
    println("Average order value: $${String.format("%.2f", if (processedOrders > 0) totalRevenue / processedOrders else 0.0)}")  
}  
  
fun performInventoryCheck(products: List<Product>) {  
    val categories = listOf("Electronics", "Accessories", "Peripherals")  
    var categoriesChecked = 0  
      
    println("Starting comprehensive inventory check...")  
      
    categoryLoop@ for ((categoryIndex, category) in categories.withIndex()) {  
        println("\nChecking category: $category")  
        var categoryHasStock = false  
          
        productLoop@ for (product in products) {  
            // Simulate category assignment based on price ranges  
            val productCategory = when {  
                product.price > 500 -> "Electronics"  
                product.price > 50 -> "Peripherals"  
                else -> "Accessories"  
            }  
              
            // Skip products not in current category  
            if (productCategory != category) {  
                continue@productLoop  
            }  
              
            println("  Checking ${product.name}...")  
              
            // If we find any out-of-stock item in Electronics, stop checking this category  
            if (category == "Electronics" && !product.inStock) {  
                println("  ⚠️  Critical item out of stock in Electronics: ${product.name}")  
                println("  Stopping Electronics category check for immediate restocking")  
                break@productLoop  
            }  
              
            if (product.inStock) {  
                categoryHasStock = true  
                println("  ✓ ${product.name} - In Stock ($${product.price})")  
            } else {  
                println("  ✗ ${product.name} - Out of Stock ($${product.price})")  
            }  
        }  
          
        categoriesChecked++  
          
        if (categoryHasStock) {  
            println("✓ Category '$category' has items in stock")  
        } else {  
            println("⚠️  Category '$category' needs restocking")  
        }  
          
        // Simulate stopping after critical category if needed  
        if (category == "Electronics" && !categoryHasStock) {  
            println("Critical inventory issue detected. Stopping full inventory check.")  
            break@categoryLoop  
        }  
    }  
      
    println("\n--- Inventory Check Summary ---")  
    println("Categories checked: $categoriesChecked/${categories.size}")  
}  
  
fun analyzePrices(products: List<Product>) {  
    println("Analyzing product prices...")  
      
    var expensiveProductsCount = 0  
    val priceThreshold = 100.0  
      
    // Using functional approach with labeled returns  
    println("\nFinding expensive products (>${priceThreshold}):")  
      
    run analysis@ {  
        products.forEach { product ->  
            if (!product.inStock) {  
                return@forEach  // Skip out-of-stock items (simulates continue)  
            }  
              
            if (product.price > priceThreshold) {  
                expensiveProductsCount++  
                println("  ${product.name}: $${product.price}")  
                  
                // Stop after finding 3 expensive products  
                if (expensiveProductsCount >= 3) {  
                    println("  Found enough expensive products for analysis")  
                    return@analysis  // Simulates break  
                }  
            }  
        }  
    }  
      
    println("\nPrice analysis completed.")  
    println("Expensive products found: $expensiveProductsCount")  
}  

Expected Output

When you run this complete program, you’ll see output like this:

=== E-commerce Order Processing System ===  
  
Processing customer orders...  
  
Processing order 1: Product ID 1, Quantity 2  
✓ Order processed successfully!  
  Product: Laptop  
  Unit Price: $999.99  
  Quantity: 2  
  Order Total: $1999.98  
  
Processing order 2: Product ID 2, Quantity 1  
Product 'Mouse' is out of stock. Skipping order.  
  
Processing order 3: Product ID 3, Quantity 3  
✓ Order processed successfully!  
  Product: Keyboard  
  Unit Price: $79.99  
  Quantity: 3  
  Order Total: $239.97  
  
Processing order 4: Product ID 4, Quantity 1  
✓ Order processed successfully!  
  Product: Monitor  
  Unit Price: $299.99  
  Quantity: 1  
  Order Total: $299.99  
  
Processing order 5: Product ID 5, Quantity 2  
Product 'Webcam' is out of stock. Skipping order.  
  
Reached maximum order processing limit (4)  
  
--- Order Processing Summary ---  
Total orders processed: 3  
Total revenue generated: $2539.94  
Average order value: $846.65  
  
=== Inventory Management ===  
  
Starting comprehensive inventory check...  
  
Checking category: Electronics  
  Checking Laptop...  
  ✓ Laptop - In Stock ($999.99)  
  Checking Monitor...  
  ✓ Monitor - In Stock ($299.99)  
✓ Category 'Electronics' has items in stock  
  
Checking category: Accessories  
  Checking Mouse...  
  ✗ Mouse - Out of Stock ($25.5)  
⚠️  Category 'Accessories' needs restocking  
  
Checking category: Peripherals  
  Checking Keyboard...  
  ✓ Keyboard - In Stock ($79.99)  
  Checking Webcam...  
  ✗ Webcam - Out of Stock ($89.99)  
  Checking Speakers...  
  ✓ Speakers - In Stock ($129.99)  
✓ Category 'Peripherals' has items in stock  
  
--- Inventory Check Summary ---  
Categories checked: 3/3  
  
=== Price Analysis ===  
  
Analyzing product prices...  
  
Finding expensive products (>100.0):  
  Laptop: $999.99  
  Monitor: $299.99  
  Speakers: $129.99  
  Found enough expensive products for analysis  
  
Price analysis completed.  
Expensive products found: 3  

This comprehensive example demonstrates how Kotlin break continue statements work in real-world scenarios, combining basic usage, labeled control flow, functional programming approaches, and practical business logic. The code shows how these control statements help create efficient, readable, and maintainable applications.

The key takeaways from mastering Kotlin break continue statements include understanding when to use each statement, leveraging labels for complex nested loops, and knowing how to simulate similar behavior in functional programming contexts. These powerful tools will help you write more efficient Kotlin code for any application, whether you’re developing Android apps, server-side applications, or any other Kotlin project.