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

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

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

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


person petergrenby    schedule 24.11.2018    source источник


Ответы (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);

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

person Sweeper    schedule 24.11.2018