如何使用Java8查找文本文件中的单词总数、元音总数、特殊字符总数

如何使用Java8查找文本文件中的单词总数、元音总数、特殊字符总数,java,lambda,java-8,java-stream,Java,Lambda,Java 8,Java Stream,我有一个文本文件,我想检查 -文件中的总字数 -文件中的元音总数 -文件中的特殊字符总数 通过使用Java8流 如果可能的话,我希望在一次迭代中以映射的形式输出 {"totalWordCount":10,"totalVowelCount":10,"totalSpecialCharacter":10} 我试过下面的代码 Long wordCount=Files.lines(child).parallel().flatMap(line -> Arrays.stream(line.tr

我有一个文本文件,我想检查
-文件中的总字数
-文件中的元音总数
-文件中的特殊字符总数

通过使用Java8流

如果可能的话,我希望在一次迭代中以映射的形式输出

{"totalWordCount":10,"totalVowelCount":10,"totalSpecialCharacter":10}
我试过下面的代码

    Long wordCount=Files.lines(child).parallel().flatMap(line -> Arrays.stream(line.trim().split(" ")))
                            .map(word -> word.replaceAll("[^a-zA-Z]", "").toLowerCase().trim())
                            .filter(word -> !word.isEmpty())
                            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())).values().stream().reduce(0L, Long::sum)

但它只给出了单词总数,我在想,是否有可能返回一个单独的映射,其中包含上述所有计数的输出。

如果我们只需要计算特殊字符和元音,我们可以使用如下内容:

Map<String,Long> result;
try(Stream<String> lines = Files.lines(path)) {
    result = lines
        .flatMap(Pattern.compile("\\s+")::splitAsStream)
        .flatMapToInt(String::chars)
        .filter(c -> !Character.isAlphabetic(c) || "aeiou".indexOf(c) >= 0)
        .mapToObj(c -> "aeiou".indexOf(c)>=0? "totalVowelCount": "totalSpecialCharacter")
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
}
这将在结果映射中添加一个
“totalalphasoric”
类别以及其他类别。如果您不想这样做,可以在
mapToObj
collect
步骤之间插入
.filter(cat->!cat.equals(“totalalphastic”)
步骤。或者使用类似于
mapToObj
步骤之前的第一个解决方案中的过滤器

另外需要注意的是,此解决方案所做的工作比必要的多,因为它将输入拆分为行,这是不必要的,因为我们可以像处理其他空白一样处理换行符,即作为单词边界。从Java 9开始,我们可以使用
Scanner
进行作业:

Map<String,Long> result;
try(Scanner scanner = new Scanner(path)) {
    result = scanner.findAll("\\S+")
        .flatMapToInt(w -> IntStream.concat(IntStream.of(-1), w.group().chars()))
        .mapToObj(c -> c==-1? "totalWordCount": "aeiou".indexOf(c)>=0? "totalVowelCount":
                Character.isAlphabetic(c)? "totalAlphabetic": "totalSpecialCharacter")
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
}
Map结果;
尝试(扫描仪=新扫描仪(路径)){
结果=scanner.findAll(\\S+)
.flatMapToInt(w->IntStream.concat(IntStream.of(-1),w.group().chars())
.mapToObj(c->c==-1?“totalWordCount”:“aeiou”。indexOf(c)>=0?“totalWordCount”:
字符。isAlphabetic(c)?“totalAlphabetic”:“totalSpecialCharacter”)
.collect(Collectors.groupingBy(Function.identity()、Collectors.counting());
}
这将首先将输入拆分为单词,而无需特别处理换行符。包含与Java 8兼容的
Scanner.findAll
实现


上面的解决方案考虑了不是空白的字符,也不是字母的“特殊字符”。如果您对“特殊角色”的定义不同,那么调整解决方案应该不会太难。

本网站通常不会很好地收到仅限需求的问题。对于特定的编程问题也是如此,关于已经存在的代码。如果您有当前的解决方案,请包括您的解决方案。您尝试了什么,但由于某些东西不起作用而被卡在哪里?作为一个已经在StackOverflow上收集了300多个声誉的人,我很惊讶您没有意识到请求列表不是一个问题。请包括您的解决方案以及您在该解决方案中遇到的问题。各位,我已更新,请检查..请删除保留标记我已更新我的问题
Map<String,Long> result;
try(Scanner scanner = new Scanner(path)) {
    result = scanner.findAll("\\S+")
        .flatMapToInt(w -> IntStream.concat(IntStream.of(-1), w.group().chars()))
        .mapToObj(c -> c==-1? "totalWordCount": "aeiou".indexOf(c)>=0? "totalVowelCount":
                Character.isAlphabetic(c)? "totalAlphabetic": "totalSpecialCharacter")
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
}