Java 8 Stream API для Rubyist

В этом посте я покажу, как решить ту же проблему с помощью API Java Stream по сравнению с использованием Ruby. Пожалуйста, ознакомьтесь с решениями, написанными на Ruby и Java, чтобы получить общее представление о Java Stream API.

Представьте проблему

Вот задача, над которой мы работаем сегодня: для каждого слова в данном предложении подсчитайте количество различных гласных и верните список подсчета.

Например, с входной строкой: «Это пример предложения.» Программа, которую мы предполагаем написать, вернет массив [1, 1, 1, 2, 1, 1]. В слове «это» всего 1 гласная, то есть яв слове «is» 1 гласная, в «a» 1 гласная, в «example» 3 гласных, а буква «e» встречается дважды, только одна из них является счетной, поэтому количество дистантных гласных в слове » пример» равен 2. Та же логика применяется к слову «предложение», потому что буква «e» встречается 3 раза и считается за 1 букву.

Разработка решения

Мне нравится идея разбивать сложные операции на несколько более мелких шагов. Давайте определим шаги, которые мы должны предпринять, чтобы вернуть выходной массив.

  1. Мы разбиваем массив на список слов.
  2. Для каждого слова мы извлекаем все гласные в список.
  3. Мы собираем только отдельные гласные из каждого списка гласных.
  4. Мы получаем размер каждого списка и сопоставляем его с конечным результатом.

С учетом примера ввода, упомянутого в предыдущем разделе, вот как он преобразовывался на каждом этапе:

Без названия Диаграмма.png

Рубиновое решение

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 Stream<String> vowels(String[] characters) {
    List<String> vowels = asList("a", "i", "o", "e", "u");
    return Stream.of(characters).filter(vowels::contains);
  }

  public List<Integer> 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. Stream API — это функциональный способ написания кода. Это позволяет разработчику больше сосредоточиться на потоке данных, а не на деталях реализации.

Код Ruby использует Enumerable, который включен в Core Ruby. Это способ по умолчанию для обработки набора данных.

Когда я реализовал решение на Ruby и на Java, я обнаружил, что между этими двумя языками есть некоторые различия. Ruby не требует от нас разделения рабочего процесса на стадию процесса и терминальную операцию, как в Java. Есть несколько вещей, которые вы можете сделать на обоих этапах, что может запутать, какой этап является правильным.


Вы можете задаться вопросом, как прийти к такому решению, или иметь какие-либо опасения по поводу потокового API и перечисления Ruby, пожалуйста, дайте мне знать, комментируя ниже.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *