gpt4 book ai didi

java - 按第一个字符对单词进行分组

转载 作者:搜寻专家 更新时间:2023-11-01 01:51:21 24 4
gpt4 key购买 nike

我有什么:逐行读取的文本文件。每个字符串包含一行。

我想要的:使用 Java Streams 按第一个字符对所有单词进行分组。

我目前拥有的:

public static Map<Character, List<String>> groupByFirstChar(String fileName)
throws IOException {

return Files.lines(Paths.get(PATH)).
flatMap(s -> Stream.of(s.split("[^a-zA-Z]"))).
map(s -> s.toLowerCase()).
sorted((s1, s2) -> s1.compareTo(s2)).
collect(Collectors.groupingBy(s -> s.charAt(0)));
}

问题:我得到一个异常

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(String.java:646)
at textana.TextAnalysisFns.lambda$16(TextAnalysisFns.java:110)
at textana.TextAnalysisFns$$Lambda$36/159413332.apply(Unknown Source)
at java.util.stream.Collectors.lambda$groupingBy$196(Collectors.java:907)
at java.util.stream.Collectors$$Lambda$23/189568618.accept(Unknown Source)
at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at java.util.stream.SortedOps$RefSortingSink$$Lambda$37/186370029.accept(Unknown Source)
at java.util.ArrayList.forEach(ArrayList.java:1249)
at java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:390)
at java.util.stream.Sink$ChainedReference.end(Sink.java:258)
at java.util.stream.Sink$ChainedReference.end(Sink.java:258)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at textana.TextAnalysisFns.groupByFirstChar(TextAnalysisFns.java:110)
at textana.SampleTextAnalysisApp.main(SampleTextAnalysisApp.java:95)

问题:为什么我会得到 StringIndexOutOfBoundException ?

根据评论提示解决:

public static Map<Character, List<String>> groupByFirstChar(String fileName)
throws IOException {

return Files.lines(Paths.get(PATH)).
flatMap(s -> Stream.of(s.split("[^a-zA-Z]"))).
filter(s -> s.length() > 0).
map(s -> s.toLowerCase()).
collect(Collectors.groupingBy(s -> s.charAt(0)));
}

用户 Eran 的解决方案一开始会给我空字符串,这是我不想拥有的。

最佳答案

尝试过滤空字符串 "",因为它们没有导致 charAt(0) 抛出此异常的第一个字符。

你可以使用

flatMap(s -> Stream.of(s.split("[^a-zA-Z]"))).
filter(s -> !s.trim().isEmpty()). //add this line

顺便说一句,您的方法可能应该使用其 fileName 参数。因此,也许可以考虑将 Paths.get(PATH) 更改为更类似的内容

Paths.get(fileName).

Paths.get(PATH).resolve(fileName)

正如评论中已经提到的那样,因为您没有更改默认比较顺序,所以您不需要显式编写

sorted((s1, s2) -> s1.compareTo(s2))

但很简单

sorted()

同样有效,因为此处将应用默认顺序。


@Alexis C. 所述groupBy 将返回 HashMap 这意味着您的 key 将不会被排序。如果您还想保留他们的顺序,您可以将 groupBy 与 LinkedHashMap 一起使用

.collect(Collectors.groupingBy(s -> s.charAt(0), LinkedHashMap::new, Collectors.toList()));

关于java - 按第一个字符对单词进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30012600/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com