|
| 1 | +# `charAt()` and `substring()` |
| 2 | + |
| 3 | +```java |
| 4 | +import java.util.ArrayList; |
| 5 | +import java.util.Arrays; |
| 6 | +import java.util.HashSet; |
| 7 | + |
| 8 | +class PigLatinTranslator { |
| 9 | + |
| 10 | + private static final HashSet < Character > vowels = new HashSet < Character > (Arrays.asList('a', 'e', 'i', 'o', 'u')); |
| 11 | + private static final HashSet < String > specials = new HashSet < String > (Arrays.asList("xr", "yt")); |
| 12 | + |
| 13 | + public String translate(String phrase) { |
| 14 | + ArrayList < String > piggyfied = new ArrayList < String > (); |
| 15 | + var words = phrase.split(" "); |
| 16 | + |
| 17 | + for (String word: words) { |
| 18 | + if (vowels.contains(word.charAt(0)) || specials.contains(word.substring(0, 2))) { |
| 19 | + piggyfied.add(word + "ay"); |
| 20 | + continue; |
| 21 | + } |
| 22 | + |
| 23 | + var length = word.length(); |
| 24 | + |
| 25 | + for (int pos = 1; pos < length; pos++) { |
| 26 | + var letter = word.charAt(pos); |
| 27 | + if (vowels.contains(letter) || letter == 'y') { |
| 28 | + if (letter == 'u' && word.charAt(pos - 1) == 'q') pos += 1; |
| 29 | + piggyfied.add(word.substring(pos) + word.substring(0, pos) + "ay"); |
| 30 | + break; |
| 31 | + } |
| 32 | + } |
| 33 | + } |
| 34 | + return String.join(" ", piggyfied); |
| 35 | + } |
| 36 | +} |
| 37 | +``` |
| 38 | + |
| 39 | +This approach starts by importing from packages for what will be needed. |
| 40 | + |
| 41 | +The class defines two [`private`][private] [`static`][static] [`final`][final] [`HashSet`][hashset]s to define the vowels |
| 42 | +and special letter sequences. |
| 43 | +They are `private` because they don't need to be directly accessed from outside the class, and `final` |
| 44 | +because they don't need to be reassigned after being created. |
| 45 | +They are `static` because they don't need to differ between object instantiations, so they can belong to the class itself. |
| 46 | + |
| 47 | +The `translate()` method starts be defining the [`ArrayList()`][arraylist] to hold the words to be output. |
| 48 | +The input `String` is then [`split()`][split] on a space to create the array of words. |
| 49 | + |
| 50 | +A [for-each][for-each] loop is used to iterate the words. |
| 51 | + |
| 52 | +An `if` statement checks if the first character in the word is a vowel. |
| 53 | +It does this by using the `String` [`charAt()`][charat] method to get the character at the first index of the word. |
| 54 | +It then uses the `HashSet` [`contains()`][contains] method to see if the `HashSet` of vowels contains the character. |
| 55 | +If so, the logical OR operator (`||`) [short circuits][short-circuit] and `ay` is concatenated to the word, which is then |
| 56 | +[`add`][add]ed to the output `ArrayList`, and the loop [continue][continue]s. |
| 57 | + |
| 58 | +If the first character is not a vowel, the other side of the `OR` operator checks if the first two characters |
| 59 | +of the word are a special sequence. |
| 60 | +It does this by using the `String` [`substring()`][substring-two] method to get a `String` of the first two characters |
| 61 | +of the word. |
| 62 | +It then uses the `HashSet.contains()` method to see if the `HashSet` of special sequences contains the substring. |
| 63 | +If so, then `ay` is concatenated to the word, which is then added to the `ArrayList`, and the loop continues. |
| 64 | + |
| 65 | +If the word does not start with a vowel or special sequence of letters, then the length of the word |
| 66 | +is set to prepare for iterating through the word characters, starting with the second character at index `1`. |
| 67 | + |
| 68 | +Inside a [`for`][for-loop] loop, the character at the current iterating index is set. |
| 69 | +The `HashSet.contains()` method is used to see if the `HashSet` of vowels contains the character. |
| 70 | +If not, the other side of the logical `OR` operator checks to see if the character is a `y`. |
| 71 | +If the character is a vowel or `y`, then the character is checked to see if it is a `u`, and, if so, |
| 72 | +if the previous character is a `q`. |
| 73 | +If the index is at the end of a `qu` sequence, then the index is incremented by `1`, otherwise the index is left as is. |
| 74 | +Finally, the word is made into Pig Latin by getting a [`substring()`][substring-one] from the index until the end of the word, |
| 75 | +to which is concatenated a [`substring()`][substring-two] from the beginning of the word up to but not including the indexed character, |
| 76 | +and concatenating `ay`. |
| 77 | + |
| 78 | +```exercism/note |
| 79 | +Note that there are two overloads of the `substring()` method. |
| 80 | +One takes one argument which will return a substring from the index of the argument until the end of the `String`. |
| 81 | +The other takes two arguments: the starting index and the ending index. |
| 82 | +It returns a substring from the starting index up to but not including the ending index. |
| 83 | +``` |
| 84 | + |
| 85 | +After all of the words are iterated, the `ArrayList` of words is assembled into a single `String` by using the |
| 86 | +[`String.join()`][join] method to join all of the words together, separated by a single space, |
| 87 | +and that `String` is returned from the function. |
| 88 | + |
| 89 | +[charat]: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#charAt(int) |
| 90 | +[substring-one]: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring(int) |
| 91 | +[substring-two]: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring(int,%20int) |
| 92 | +[split]: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String) |
| 93 | +[private]: https://en.wikibooks.org/wiki/Java_Programming/Keywords/private |
| 94 | +[static]: https://en.wikibooks.org/wiki/Java_Programming/Keywords/static |
| 95 | +[final]: https://en.wikibooks.org/wiki/Java_Programming/Keywords/final |
| 96 | +[hashset]: https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/util/HashSet.html |
| 97 | +[arraylist]: https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html |
| 98 | +[for-each]: https://www.geeksforgeeks.org/for-each-loop-in-java/ |
| 99 | +[contains]: https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/util/HashSet.html#contains(java.lang.Object) |
| 100 | +[add]: https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#add-E- |
| 101 | +[short-circuit]: https://www.geeksforgeeks.org/short-circuit-logical-operators-in-java-with-examples/ |
| 102 | +[continue]: https://www.geeksforgeeks.org/continue-statement-in-java/ |
| 103 | +[for-loop]: https://www.geeksforgeeks.org/java-for-loop-with-examples/ |
| 104 | +[join]: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#join(java.lang.CharSequence,java.lang.Iterable) |
0 commit comments