简体   繁体   English

"如何通过函数式编程计算Java中的元音?"

[英]How to count vowels in Java through functional programming?

I need to count the number of vowels in a list of words in Functional Java.我需要计算函数式 Java 中单词列表中元音的数量。 If I have this list:如果我有这个清单:

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

How about this:这个怎么样:

List<String> vowels = Arrays.asList("a", "e", "i", "o", "u");

int count Arrays.stream(string.split(""))  // generate stream from an String[] of single character strings
    .filter(vowels::contains)  // remove all non-vowels
    .count();  // count the elements remaining

You can eliminate multiple map with one map using replaceAll您可以使用replaceAll用一张map消除多个map

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

[aeiou] it will match any char inside [] and replace it with empty string [aeiou]它将匹配[]内的任何字符并将其替换为空字符串

I'd break it to stream of chars, filter only vowels and then count:我会将它分解为字符流,仅过滤元音然后计数:

int tot = l.stream()
  .flatmap(s -> s.chars().stream())
  .filter(c -> c == 'a' || c == 'e' ||c == 'i' ||c == 'o' ||c == 'u')
  .count();

You're probably concerned about the multiple replace calls, which isn't really related to functional programming.您可能担心多次replace调用,这与函数式编程并没有真正的关系。 One way to replace those calls is to use a regular expression and replaceAll :替换这些调用的一种方法是使用正则表达式和replaceAll

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

This single map replaces all 5 maps that removes the vowels.这个单一的地图取代了所有 5 个去除元音的地图。

With a regular expression, you could also remove all the non-vowels.使用正则表达式,您还可以删除所有非元音。 This way, you don't have to subtract tot :这样,您不必减去tot

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

Now you still have two consecutive map s, you can combine them into one:现在你还有两个连续的map ,你可以将它们合二为一:

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

This is now more functional because I've removed the step of subtracting tot .这现在更实用,因为我删除了减去tot的步骤。 This operation is now described only as a composition of function (as far as this level of abstraction is concerned), instead of a bunch of "steps".这个操作现在只被描述为一个函数的组合(就这个抽象级别而言),而不是一堆“步骤”。

Function<String,Integer> vowelsCount = s -> {
        List<Character> vowels = new ArrayList<>(Arrays.asList('a', 'e', 'i', 'o', 'u'));
        s = s.toLowerCase();
        int countVowels = 0;
        for (int index = 0; index < s.length(); index++) {
            char currentChar = s.charAt(index);
            if (vowels.contains(currentChar)) {
                countVowels++;
            }
        }
        return countVowels;
    };
    String str = "Lambda expression pattern";
    System.out.printf("%s ==> %d",str, vowelsCount.apply(str));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM