Автор оригинала: K’vin.
В этом посте я покажу, как решить ту же проблему с помощью Java Stream API по сравнению с использованием Ruby. Пожалуйста, ознакомьтесь с решениями, написанными на Ruby и Java, чтобы получить общее представление об API Java Stream.
Представьте проблему
Вот проблема, над которой мы работаем сегодня: Для каждого слова в данном предложении подсчитайте количество различных гласных и верните список подсчета.
Например, с помощью входной строки: “Это пример предложения.”, программа, которую мы предполагаем написать, вернет массив [1, 1, 1, 2, 1, 1] . В слове “это” есть только 1 гласная, которая является i , в слове “есть” 1 гласный, в “а” 1 гласный, в “примере” 3 гласных, а буква “е” появляется дважды, только один из них считается, поэтому количество выделенных гласных для слова “пример” равно 2. Та же логика применяется и к слову “предложение”, потому что буква “е” встречается 3 раза и считается 1 буквой.
Разработайте решение
Мне нравится идея разбить сложные операции на несколько более мелких шагов. Давайте определим шаги, которые мы должны предпринять, чтобы вернуть выходной массив.
- Мы разделяем массив на список слов.
- Для каждого слова мы извлекаем все гласные в список.
- Мы собираем только отдельные гласные из каждого списка гласных.
- Мы получаем размер каждого списка и сопоставляем его с конечным результатом.
С учетом примера ввода, упомянутого в предыдущем разделе, вот как он преобразовывался на каждом этапе:
Решение Ruby
VOWELS = %w(a e o u i A E O U I) sentence = "This is an example of sentence" def count_vowels(sentence) sentence .split .map(&:chars) .map { |chars| vowels(chars) } .map(&:uniq) .map(&:size) end def vowels(chars) chars.select { |char| VOWELS.include?(char) } end puts count_vowels(sentence).inspect
Решение Java
private Streamvowels(String[] characters) { List vowels = asList("a", "i", "o", "e", "u"); return Stream.of(characters).filter(vowels::contains); } public List countVowels(String sentence) { return Arrays.stream(sentence.split(" ")) .map(word -> word.split("")) .map(this::vowels) .map(vowelsStream -> vowelsStream.distinct().collect(toList())) .map(List::size) .collect(toList()); }
Так как же?
Код кажется чистым для обеих реализаций. Код объясняется сам по себе, а синтаксис прост.
Код Java написан с использованием Java 8 Stream API. Это огромное улучшение в языке Java. Потоковый API-это функциональный способ написания кода. Это позволяет разработчику больше сосредоточиться на потоке данных, а не на деталях реализации.
Код Ruby использует Enumerable, который включен в основной Ruby. Это способ обработки сбора данных по умолчанию.
Когда я реализовал решение на Ruby и на Java, я обнаружил, что между этими двумя языками есть некоторые различия. Ruby не требует, чтобы мы разделяли рабочий процесс на стадию процесса и терминальную операцию, как Java. Есть пара вещей, которые вы можете сделать на обоих этапах, что может привести к путанице, на каком этапе это правильно.
Вы можете задаться вопросом, как найти подобное решение, или у вас есть какие-либо опасения по поводу API потока и перечисляемого Ruby, пожалуйста, дайте мне знать, прокомментировав ниже.
Оригинал: “https://www.codementor.io/@duykhoa12t/java-8-stream-api-for-rubyist-x7pcvya2u”