Использование java-потоков для сжатия данных

Я пытался найти пример того, как использовать Java-потоки в качестве компрессора. Я до сих пор не понял, как это сделать, и я не нашел никого, кто бы это сделал. Поэтому я хотел бы подсчитать вхождения в поток чего-либо, пока они находятся в непрерывной строке. Простой пример будет примерно таким:

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

Просто получить строку в поток целых чисел и сосчитать их вхождения. Но посчитать вхождения в непрерывной последовательности я не могу понять, как это сделать. Есть ли хороший способ использовать .reduce, чтобы это произошло?

1 ответ

Я не думаю StreamЭто подходящая вещь для кодирования длин серий. Потоки и состояния просто не очень хорошо сочетаются друг с другом. Чтобы вести подсчет количества уже подсчитанных вами символов, неизбежно будет задействовано состояние. Один из способов сделать это - использовать reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner) и передавайте ему анонимные классы (да, анонимные классы), и в этих анонимных классах вы можете хранить переменную, которая записывает, сколько символов существует. Вы можете использовать StringBuilders, чтобы добавить закодированные строки. Это не элегантное решение.

Я немного креативен и сделал это:

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);

Я действительно использую потоки, но я немного обманул и использовал регулярное выражение:).

Другие вопросы по тегам