7

I need to count the number of vowels in a list of words in Functional Java. If I have this list:

List<String> l = Arrays.asList("hello", "world", "test");

My idea was to "delete" the vowels and then do a subtraction this way:

int tot = l.stream().map(s -> s.replace("a", "")).
            map(s -> s.replace("e", "")).
            map(s -> s.replace("i", "")).
            map(s -> s.replace("o", "")).
            map(s -> s.replace("u", "")).
            map(s -> s.length()).reduce(0, Integer::sum);
int res = l.stream().map(s->s.length()).reduce(0, Integer::sum)-tot;

Is there a better way to do this?

4

5 に答える 5

4

を使用mapして、1つで複数を削除できますmapreplaceAll

    int tot = l.stream()
               .map(s -> s.replaceAll("[aeiou]", "").length())
               .reduce(0, Integer::sum);

[aeiou]内部の任意の文字と一致[]し、空の文字列に置き換えます

于 2020-01-31T17:22:59.957 に答える
2

文字のストリームに分割し、母音のみをフィルタリングしてからカウントします。

int tot = l.stream()
  .flatmap(s -> s.chars().stream())
  .filter(c -> c == 'a' || c == 'e' ||c == 'i' ||c == 'o' ||c == 'u')
  .count();
于 2020-01-31T17:22:54.930 に答える
1

replaceおそらく、関数型プログラミングとはあまり関係のない複数の呼び出しについて心配しているでしょう。これらの呼び出しを置き換える 1 つの方法は、正規表現 and を使用することreplaceAllです。

.map(s -> s.replaceAll("[aeiou]", ""))

この単一のマップは、母音を削除する 5 つのマップすべてを置き換えます。

正規表現を使用すると、非母音をすべて削除することもできます。このように、減算する必要はありませんtot:

int vowels = l.stream().map(s -> s.replaceAll("[^aeiou]", ""))
                        .map(s -> s.length()).reduce(0, Integer::sum);
// no need to do anything else!

2 つの連続した が残っているのでmap、それらを 1 つに結合できます。

int vowels = l.stream().map(s -> s.replaceAll("[^aeiou]", "").length())
                        .reduce(0, Integer::sum);

を減算するステップを削除したため、これはより機能的になりましたtot。この操作は、一連の「ステップ」ではなく、(このレベルの抽象化に関する限り) 関数の構成としてのみ記述されます。

于 2020-01-31T17:27:54.127 に答える