Problem overview
The method shout gets a list of lowercase words and returns a new list in which every word is written in capital letters with ! after it. The order stays the same. So ["hey", "you"] becomes [HEY!, YOU!], ["go"] becomes [GO!], and a repeated word is shouted every time: ["no", "no", "no"] becomes [NO!, NO!, NO!].
Approach
Every input word turns into exactly one output word, in the same place. That is the job of map. A stream hands the words over one by one, a lambda turns each one into its shouted version, and toList() collects the results in a new list. There is nothing to skip, so no filter is needed.
Step by step
- Build a
List<String>namedshouted. Callstream()onwords, thenmapwith a lambda that returnsword.toUpperCase() + "!", thentoList().toUpperCase()returns a new string in capital letters, and+puts the!at the end. - Return
shouted. The new list is the answer, andwordsitself isn't changed.
The solution in Java
class Solution {
public List<String> shout(List<String> words) {
List<String> shouted = words.stream().map(word -> word.toUpperCase() + "!").toList();
return shouted;
}
}
Strings in Java can't be changed, so toUpperCase() never edits the original word. It returns a new string, and the lambda gives that new string back to map. The output list is as long as the input list, because map makes one result for each item.
Edge cases and common mistakes
- Calling
toUpperCase()without using the result.word.toUpperCase();on its own line throws the new string away. In the lambda, the expression after->is what comes back. - Forgetting
toList().mapalone gives a stream, not a list, so it doesn't fit the method's return type. - Adding the
!before the conversion. It makes no difference here, since!has no case, but the clear order is: convert the word, then add the mark. - Trying to change the result. The list from
toList()can't be modified:addon it throwsUnsupportedOperationException. The method doesn't need to change it. - Repeated words. Every copy is mapped, so
["no", "no", "no"]gives three results.
Testing
Try these inputs:
["hey", "you"]gives[HEY!, YOU!].["go"]gives[GO!].["no", "no", "no"]gives[NO!, NO!, NO!].
The order never changes, because the stream visits the words in list order and toList() keeps that order. The length of the result always equals the length of the input.
The same shape fits any job where each item becomes exactly one new item: adding a prefix, taking each word's length, or trimming each string. When some items should be dropped, add a filter before the map, as in the squares exercise.
One detail for programs of your own: toUpperCase() with no argument follows the computer's default language settings, which can change how some letters convert (a Turkish setting turns i into a dotted capital İ). For plain English letters it is what you expect, and you can write toUpperCase(Locale.ROOT) when the result must not depend on the machine.
The input words are lowercase letters only, so no word needs any other cleaning.
