Java provides additional means for altering control flow within a loop: the continue statement, the break statement, the labeled break statement, and the labeled continue statement. The break StatementYou may want to prematurely terminate the execution of a loop. If the Java VM encounters a break statement within the body of a loop, it immediately transfers control to the statement following the loop body. The String class defines a trim method that removes blank characters[5] from both ends of a String. You will define another String utility that trims blank characters from only the end of a String.
public void testEndTrim() { assertEquals("", endTrim("")); assertEquals(" x", endTrim(" x ")); assertEquals("y", endTrim("y")); assertEquals("xaxa", endTrim("xaxa")); assertEquals("", endTrim(" ")); assertEquals("xxx", endTrim("xxx ")); } public String endTrim(String source) { int i = source.length(); while (i >= 0) if (source.charAt(i) != ' ') break; return source.substring(0, i + 1); } The continue StatementWhen it encounters a continue statement, Java immediately transfers control to the conditional expression of a loop.
public void testAverageGpaForPartTimeStudents() { session.enroll(createFullTimeStudent()); Student partTimer1 = new Student("1"); partTimer1.addGrade(Student.Grade.A); session.enroll(partTimer1); session.enroll(createFullTimeStudent()); Student partTimer2 = new Student("2"); partTimer2.addGrade(Student.Grade.B); session.enroll(partTimer2); assertEquals(3.5, session.averageGpaForPartTimeStudents(), 0.05); } private Student createFullTimeStudent() { Student student = new Student("a"); student.addCredits(Student.CREDITS_REQUIRED_FOR_FULL_TIME); return student; } The implementation (in Session) demonstrates use of the continue statement to skip students that are not part-time. double averageGpaForPartTimeStudents() { double total = 0.0; int count = 0; for (Student student: students) { if (student.isFullTime()) continue; count++; total += student.getGpa(); } if (count == 0) return 0.0; return total / count; } You can easily rewrite this (and most) uses of continue using if-else statements. Sometimes the use of continue provides the more-elegant, easy-to-read presentation. Labeled break and continue StatementsThe labeled break and continue statements allow you to transfer control when you have more complex nesting. The first example tests a labeled break. Don't let the interesting declaration of table scare you. List<List<Integer>> declares a list into which you can put lists bound to the Integer type. public void testLabeledBreak() { List<List<String>> table = new ArrayList<List<String>>(); List<String> row1 = new ArrayList<String>(); row1.add("5"); row1.add("2"); List<String> row2 = new ArrayList<String>(); row2.add("3"); row2.add("4"); table.add(row1); table.add(row2); assertTrue(found(table, "3")); assertFalse(found(table, "8")); } private boolean found(List<List<String>> table, String target) { boolean found = false; search: for (List<String> row: table) { for (String value: row) { if (value.equals(target)) { found = true; break search; } } } return found; } If you did not associate the search label with the break statement in this example, Java would break out of only the innermost for loop (the one with the expression Integer num: row). Instead, the break statement causes looping to terminate from the search label, representing the outermost loop in this example. The labeled continue statement works similarly, except the Java VM transfers control to the loop with the label instead of breaking from the loop with the label. There are few situations where your solution will require labeled break or continue statements. In most cases, you can easily restructure code to eliminate them, either by use of if-else statements or, even better, by decomposition of methods into smaller, more composed methods. Use the labeled statements only when the solution is easier to comprehend. |