I have a String:
String modulesToUpdate = "potato:module1, tomato:module2";
I want to get from it only:
module1
module2
First I have to split it with "," and then with ":"
So, I did this:
String files[] = modulesToUpdate.split(",");
for(String file: files){
String f[] = file.split(":");
for(int i=0; i<f.length; i++){
System.out.println(f[1])
}
}
This works, but loop in the loop is not elegant.
I'm trying to do the same thing with streams.
So, I did this:
Stream.of(modulesToUpdate)
.map(line -> line.split(","))
.flatMap(Arrays::stream)
.flatMap(Pattern.compile(":")::splitAsStream)
.forEach(f-> System.out.println(f.toString().trim()));
Output:
potato
module1
tomato
module2
How to reduce/filter it to get only:
module1
module2
Change a single line:
.map(x -> x.split(":")[1])
instead of:
.flatMap(Pattern.compile(":")::splitAsStream)
Or as @Holger mentions in the comment:
.map(s -> s.substring(s.indexOf(':')+1))
this does not create the intermediate array at all.
That flatMap
is returning a Stream
and Streams don't have indexes, but you do need them in this case to get to the second token.
The split
operation can do all your steps at once.
Consider splitting with the separator pattern ,\s*
instead of just ,
to get rid of the need for a subsequent trim
operation. Likewise, we can treat the unwanted prefix (matching [^:]*?:
) as part of the separator, to remove it.
There’s only one thing left; the first element has a prefix which is not treated as separator. We may do either, remove it manually before the stream operation
Pattern.compile(",\\s*[^:]*?:")
.splitAsStream(modulesToUpdate.substring(modulesToUpdate.indexOf(':')+1))
.forEach(System.out::println);
or we allow a prefix at the beginning of the string to be treated like a separator, which lets the split operation handle it, but creates an empty string at the beginning, which we have to skip
Pattern.compile("(^|,\\s*)[^:]*?:").splitAsStream(modulesToUpdate)
.skip(1)
.forEach(System.out::println);
You can use skip
inside flatMap
, e.g.:
String modulesToUpdate = "potato:module1, tomato:module2";
Arrays.stream(modulesToUpdate.split(","))
.map(String::trim)
.flatMap(s -> Arrays.stream(s.split(":")).skip(1))
.forEach(System.out::println);
maybe another option can be:
String modulesToUpdate = "potato:module1, tomato:module2";
String[] mod = modulesToUpdate.split("[:,]");
List<String> res = IntStream.range(0, mod.length)
.filter(j -> (j % 2) == 0)
.mapToObj(i -> mod[i])
.collect(Collectors.toList());
System.out.println(res);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With