Requirement
Given a sentence comprising of one or multiple words separated by space (e.g. java
, Hello World
, aadsbbaba
), return a sorted list of distinct characters excluding space
Solve this problem using Java Stream
Hint: Use String.split(“”)
to split a string into a String[]
, then use String.charAt(0)
to convert each single-char string to char
Discussion
This problem tests candidate’s knowledge of the following Stream
methods:
Stream.of(...)
orArray.stream(...)
to convert an array of single-char string (e.g. fromstr.split("")
) toStream<String>
map(str -> str.charAt(0))
to convertString
toCharacter
. Note: whileString.toCharArray
can readily convert aString
to anchar[]
, turning the resulting array to aCharacter
stream isn’t straightforward due to lack of built-in support forchar
type in Stream and Collection API. TheArrays.asList(str.toCharArray()
orList.of(...)
results in aList<char[]>
insteaddistinct()
to keep only 1 instance of each encountered charactersorted()
to sort the encountered characters in their natural ordercollect(Collectors.toList())
to collect stream elements into a list
Sample Solution
A sample solution is shown below. In addition to above operations, we only utilize an extra filter(...)
operation to discard spaces from getting into our response
public static List<Character> distinctCharsStream2(String sentence) {
return Arrays.stream(sentence.split(""))
.map(s -> s.charAt(0))
.filter(i -> i != ' ')
.distinct()
.sorted()
.collect(Collectors.toList());
}
Recall again the use of String.split("")
and String.charAt(0)
instead of String.toCharArray()
. Due to the lack of built-in support for char
type in Stream and Collection API, Arrays.asList(sentence.toCharArray())
or List.of(sentence.toCharArray())
result in a List<char[]>
instead of List<Character>
that we need
Extra
Instead of a sentence string, candidate shall be given an list of words.
This modification results in mostly the same solution as the original problem, with 2 twists:
- Spaces are omitted
- Candidate may use
flatMap
to merge characters from each word into a singleStream<Character>
words.stream()
.flatMap(word -> Stream.of(word.split("")))
.map(s -> s.charAt(0))
...
A small modification to the sample solution can lead us to the same flatMap(...)
usage
return Arrays.stream(sentence.split(" "))
.flatMap(word -> Stream.of(word.split("")))
...
Imperative Solution
If we omit the Stream requirement, some candidate may derive an imperative solution using loop and Set
Set<Character> characters = new HashSet<>();
for (char c : sentence.toCharArray()) {
if (c == ' ') continue;
characters.add(c);
}
List<Character> result = new ArrayList<>(characters);
result.sort((c1, c2) -> c1 - c2);
return result;
There is nothing wrong with this approach. To some extend, I think it is even more understandable than the Stream-based one.
But as functional and reactive programming become more and more popular, so does the need to master Stream operations. If there are still time, I would politely ask the candidate to convert his/her codes to Stream.

distinct characters