|
| 1 | +# nested `if` statements |
| 2 | + |
| 3 | +```java |
| 4 | +import java.util.function.Predicate; |
| 5 | +import java.util.regex.Pattern; |
| 6 | + |
| 7 | +class Bob { |
| 8 | + |
| 9 | + final private static Pattern isAlpha = Pattern.compile("[a-zA-Z]"); |
| 10 | + final private static Predicate < String > isShout = msg -> isAlpha.matcher(msg).find() && msg == msg.toUpperCase(); |
| 11 | + |
| 12 | + public String hey(String message) { |
| 13 | + var speech = message.trim(); |
| 14 | + if (speech.isEmpty()) { |
| 15 | + return "Fine. Be that way!"; |
| 16 | + } |
| 17 | + var questioning = speech.endsWith("?"); |
| 18 | + var shouting = isShout.test(speech); |
| 19 | + if (questioning) { |
| 20 | + if (shouting) { |
| 21 | + return "Calm down, I know what I'm doing!"; |
| 22 | + } |
| 23 | + return "Sure."; |
| 24 | + } |
| 25 | + if (shouting) { |
| 26 | + return "Whoa, chill out!"; |
| 27 | + } |
| 28 | + return "Whatever."; |
| 29 | + } |
| 30 | +} |
| 31 | +``` |
| 32 | + |
| 33 | +In this approach you have a series of `if` statements using the private methods to evaluate the conditions. |
| 34 | +As soon as the right condition is found, the correct response is returned. |
| 35 | + |
| 36 | +Note that there are no `else if` or `else` statements. |
| 37 | +If an `if` statement can return, then an `else if` or `else` is not needed. |
| 38 | +Execution will either return or will continue to the next statement anyway. |
| 39 | + |
| 40 | +The `String` [`trim()`][trim] method is applied to the input to eliminate any whitespace at either end of the input. |
| 41 | +If the string has no characters left, it returns the response for saying nothing. |
| 42 | + |
| 43 | +~~~~exercism/caution |
| 44 | +Note that a `null` `string` would be different from a `String` of all whitespace. |
| 45 | +A `null` `String` would throw a `NullPointerException` if `trim()` were applied to it. |
| 46 | +~~~~ |
| 47 | + |
| 48 | +A [Pattern][pattern] is defined to look for at least one English alphabetic character. |
| 49 | + |
| 50 | +The first half of the `isShout` [Predicate][predicate] |
| 51 | + |
| 52 | +```java |
| 53 | +isAlpha.matcher(msg).find() && msg == msg.toUpperCase(); |
| 54 | +``` |
| 55 | + |
| 56 | +is constructed from the `Pattern` [`matcher()`][matcher-method] method and the [`Matcher`][matcher] [`find()`][find] method |
| 57 | +to ensure there is at least one letter character in the `String`. |
| 58 | +This is because the second half of the condition tests that the uppercased input is the same as the input. |
| 59 | +If the input were only `"123"` it would equal itself uppercased, but without letters it would not be a shout. |
| 60 | + |
| 61 | +A question is determined by use of the [`endsWith()`][endswith] method to see if the input ends with a question mark. |
| 62 | + |
| 63 | +## Shortening |
| 64 | + |
| 65 | +When the body of an `if` statement is a single line, both the test expression and the body _could_ be put on the same line, like so |
| 66 | + |
| 67 | +```java |
| 68 | +if (speech.isEmpty()) return "Fine. Be that way!"; |
| 69 | +``` |
| 70 | + |
| 71 | +or the body _could_ be put on a separate line without curly braces |
| 72 | + |
| 73 | +```java |
| 74 | +if (speech.isEmpty()) |
| 75 | + return "Fine. Be that way!"; |
| 76 | +``` |
| 77 | + |
| 78 | +However, the [Java Coding Conventions][coding-conventions] advise to always use curly braces for `if` statements, which helps to avoid errors. |
| 79 | +Your team may choose to overrule them at its own risk. |
| 80 | + |
| 81 | +[trim]: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#trim() |
| 82 | +[pattern]: https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html |
| 83 | +[predicate]: https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html |
| 84 | +[matcher]: https://docs.oracle.com/javase/8/docs/api/java/util/regex/Matcher.html |
| 85 | +[matcher-method]: https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html#matcher-java.lang.CharSequence- |
| 86 | +[find]: https://docs.oracle.com/javase/8/docs/api/java/util/regex/Matcher.html#find-- |
| 87 | +[endswith]: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#endsWith(java.lang.String) |
| 88 | +[coding-conventions]: https://www.oracle.com/java/technologies/javase/codeconventions-statements.html#449 |
0 commit comments