3

I have been trying to find an example of how to use java-streams as compressor. I still have not figured out how to do this and I have neither found anyone else that done it. So that I would like to do is to count occurrences, of something, in the stream as long as they are in unbroken row. A simple example would be something like this:

String str = "...---...";
String compressed = func(str);
compressed.equals("3.3-3.");

It is simple to get string into a stream of integers and count the occurrences of them. But count the occurrences in a unbroken sequence I can not figure out how to do. Is there a good way of using .reduce to make this happen?

Robin Green
  • 32,079
  • 16
  • 104
  • 187

1 Answers1

1

I don't think Streams are a suitable thing to use for run-length encoding. Streams and states just don't generally go well together. To keep a count of how many characters you have already counted will inevitably involve state. One way you could do it is to use reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner) and pass anonymous classes (yes, anonymous classes) to it, and in those anonymous classes, you can keep a variable that records how many of a character there is. You can then use StringBuilders to append the encoded strings. This is not an elegant solution.

I got a little creative and did this:

String str = "aaaajjjfjjeeee";
String result = Pattern.compile("(?<=(.))(?!\\1)")
                    .splitAsStream(str)
                    .map(x -> 
                        Character.toString(x.charAt(0)) + 
                        Integer.toString(x.length()))
                     .collect(Collectors.joining());
System.out.println(result);

I am indeed using streams but I cheated a little bit and used a regex :).

Sweeper
  • 213,210
  • 22
  • 193
  • 313