当前位置: 首页 > 知识库问答 >
问题:

显示有限流中所有最长的单词

卓致远
2023-03-14

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

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

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

共有3个答案

经和洽
2023-03-14

迭代映射键以查找最长的字长

别帅
2023-03-14

减少将帮助您:

    Optional<String> longest = words.stream()
            .reduce((s1, s2) -> {
                if (s1.length() > s2.length())
                    return s1;
                else
                    return s2;
            });

如果为空,它将返回一个可选值。空的

如果你想要最大长度的所有单词的列表,这篇文章将帮助你:

    Optional<List<String>> longest = words.stream()
            .collect(Collectors.groupingBy(
                    String::length,
                    Collectors.toList()
            ))
            .entrySet()
            .stream()
            .reduce(
                    (entry1, entry2) -> {
                        if (entry1.getKey() > entry2.getKey())
                            return entry1;
                        else
                            return entry2;
                    }
            )
            .map(Map.Entry::getValue);
宋智明
2023-03-14

你可以将单词从它们的长度收集到单词的地图中,然后取最长的一个:

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所指出的,在流地图上使用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);

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

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;
             }
         ));
 类似资料:
  • 问题内容: 我正在使用PostgreSQL,并且在表中有一列,其中包含非常长的文本。我想在查询中选择此列,但限制其显示长度。 就像是: 我该怎么做? 问题答案: 您可以做的是使用PostgreSQL的substring()方法。以下两个命令之一将起作用:

  • 问题内容: 我试图从表中获取所有列的列表,这些列表包含它们的数据类型,数据长度和该列中最长值的长度。 我使用此SQL来获取列及其数据类型和长度: 我有此SQL,用于获取值的最大长度: 但是我不知道如何将它们结合起来。我正在使用SQL Server 2008。 问题答案: 感谢您的建议。我想出了以下解决方案。它为我获取了我需要的数据,但是希望了解它是否可以提高效率。

  • 我有这个问题: 您将获得一个整数 A 和一个整数 k 的数组。您可以将 A 的元素递减到 k 次,目标是生成一个元素都相等的连续子数组。返回可以用这种方式生成的最长的连续子数组的长度。 例如,如果 A 是 [1,7,3,4,6,5] 并且 k 是 6,那么您可以生成 [1,7,3,4-1,6-1-1-1,5-1-1] = [1,7,3,3,3,3],因此您将返回 4。 最佳解决方案是什么?

  • 我已经用RowSelectionModel和RowSelectionProvider创建了一个NatTable: 基本上,表做我想让它做的事情。只有一个例外: 该表如下所示: 所以,我现在有点卡住了。是什么导致标头单元格被突出显示,我如何改变这种行为?是否可以只突出光标单元格的标头(就像对选定行的光标单元格(2)所做的那样)?

  • 我正在制作一个JavaFX应用程序,在启动时,TextField有默认文本,上面写着“请输入这个值”,用户应该删除该文本并输入一个值。但是,每次单击、拖动和高亮显示所有文本是相当痛苦的。当用户单击文本字段时,是否有一种方法可以自动突出显示所有文本以便于删除,但只有当文本等于默认消息时才可以?我研究了这个,没有找到任何东西,任何帮助都是非常感谢的。

  • 可能这是一个幼稚的问题,但我是初学者请不要认为是错误的问题。我搜索了很多,也跟着这个 http://developer.android.com/guide/topics/ui/notifiers/notifications.html教程。还有谷歌解决我的问题,但我找不到。 这是我的作业。 我在主活动中有一个EditText和一个按钮,当我单击该按钮时生成一个通知,当我打开该通知时另一个活动打开,显