How do I use Java streams to find all differences in letter casing based on a given string input?
To solidify my understanding of Java Streams. I am solving leetcode easy questions using java streams. I am confused on how to solve this backtracking problem using streams. I am especially confused how to map a character twice ie lower case and upper case.
Input: S = "a1b2"
Output: ["a1b2","a1B2","A1b2","A1B2"]
Stream.of(S.split(""))
.map(str -> str.toUpperCase()) // this will upper case only
.map(str -> str.toLowerCase()) // this will lower case only. how to use both?
.collect(Collectors.toList()); //how do i concatenate strings before adding into list
Apologies in advance for bad english
As rzwitserloot says, this kind of problems normally are not attacked using streams, however I will try to solve the doubts you have in the question:
For a stream that has the uppercase and lowercase version of the letter you can use something like this:
Stream.of(input.split(""))
.filter(c -> Character.isLetter(c.charAt(0))) // Filter only letters
.flatMap(str -> Stream.of(str, str.toUpperCase())) // Flatten the stream with both letters
.collect(Collectors.toList())
If you want to concatenate Strings that you have in a list after mapping the values in the stream, instead of using Collectors.toList()
you can use Collectors.joining()
like this:
Stream.of(input.split(""))
.filter(c -> Character.isLetter(c.charAt(0))) // Filter only letters
.flatMap(str -> Stream.of(str, str.toUpperCase()))
.collect(Collectors.joining()) // this collector can receive a delimiter if you want to join them separated by comman for example.
Now for the problem in question, you don't need to have the upper and lower case version of the letters, just to filter the letters from the input word and the start replacing them in the word on by one for the uppercase version, this can be a possible solution:
public static void main(String[] args) {
String input = "a1b2";
// Output: ["a1b2","a1B2","A1b2","A1B2"];
Set<String> result = new HashSet<>();
result.add(input);
Stream.of(input.split(""))
.filter(c -> Character.isLetter(c.charAt(0)))
.forEach(c -> result.addAll(
result.stream().map(str -> {
if (!str.equals(input.toUpperCase())) {
return str.replaceFirst(c, c.toUpperCase());
}
return str;
}).collect(Collectors.toSet()))
);
System.out.println(result);
}