gpt4 book ai didi

java - 显示来自 finite Stream 的所有最长单词

转载 作者:行者123 更新时间:2023-12-02 06:28:52 25 4
gpt4 key购买 nike

我必须使用 Streams API 从给定文件中找到所有最长的单词。我分几步完成,但寻找一些“一个衬里”,实际上我处理了整个文件两次,第一次是找到最大单词长度,第二次是将所有单词与最大长度进行比较,假设它不是最​​好的性能; P 有人可以帮助我吗?只看代码:

public class Test {
public static void main(String[] args) throws IOException {
List<String> words = Files.readAllLines(Paths.get("alice.txt"));
OptionalInt longestWordLength = words.stream().mapToInt(String::length).max();
Map<Integer, List<String>> groupedByLength = words.stream().collect(Collectors.groupingBy(String::length));
List<String> result = groupedByLength.get(longestWordLength.getAsInt());
}
}

我想把它弄直:

List<String> words = Files.readAllLines(Paths.get("alice.txt"));
List<String> result = // code

文件每行只包含一个单词,无论如何这并不重要 - 问题是关于正确的流代码。

最佳答案

您可以将单词从长度到单词收集到一个映射中,而不是只保留最大长度,然后只取最长的一个:

List<String> longestWords =
Files.lines(Paths.get("alice.txt"))
.collect(Collectors.groupingBy(String::length))
.entrySet()
.stream()
.sorted(Map.Entry.<Integer, List<String>> comparingByKey().reversed())
.map(Map.Entry::getValue)
.findFirst()
.orElse(null);

编辑:
正如 Malte Hartwig 指出的那样,在流式 map 上使用 max 更加优雅(并且可能更快):

List<String> longestWords =
Files.lines(Paths.get("alice.txt"))
.collect(Collectors.groupingBy(String::length))
.entrySet()
.stream()
.max(Map.Entry.comparingByKey())
.map(Map.Entry::getValue)
.orElse(null);

编辑 2:
上述两种解决方案都存在内在的低效率,因为它们都构建了一个映射,本质上是存储文件中所有字符串的长度,而不仅仅是最长的字符串。如果在您的用例中性能比优雅更重要,您可以编写自己的 Collector 以仅保留列表中最长的字符串:

private static int stringInListLength(List<String> list) {
return list.stream().map(String::length).findFirst().orElse(0);
}

List<String> longestWords =
Files.lines(Paths.get("alice.txt"))
.collect(Collector.of(
LinkedList::new,
(List<String> list, String string) -> {
int stringLen = string.length();
int listStringLen = stringInListLength(list);
if (stringLen > listStringLen) {
list.clear();
}
if (stringLen >= listStringLen) {
list.add(string);
}
},
(list1, list2) -> {
int list1StringLen = stringInListLength(list1);
int list2StringLen = stringInListLength(list2);
if (list1StringLen > list2StringLen) {
return list1;
}
if (list2StringLen > list1StringLen) {
return list2;
}
list1.addAll(list2);
return list1;
}
));

关于java - 显示来自 finite Stream 的所有最长单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46341610/

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