Использование 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)
и передавайте ему анонимные классы (да, анонимные классы), и в этих анонимных классах вы можете хранить переменную, которая записывает, сколько символов существует. Вы можете использовать StringBuilder
s, чтобы добавить закодированные строки. Это не элегантное решение.
Я немного креативен и сделал это:
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);
Я действительно использую потоки, но я немного обманул и использовал регулярное выражение:).