1. 概述

在这个教程中,我们将探讨如何找出句子中的一个或所有最长的单词。一个句子是一组单词,我们用Java的String类型来表示它。另外,我们假设每个非空白字符都是单词的一部分。最后,我们会强调一些技术边缘情况:空、空格或空白的String没有最长的单词。

2. 找出最长的单词

首先,让我们找到句子中最长的单词。例如,在句子"这是一个包含单词的短语"中,最长的单词是"短语"。如果有多个单词长度相同,任何一个都是可接受的答案。如果句子没有单词,就没有结果。因此,我们的方法返回一个Optional

public Optional<String> findLongestWord(String sentence) {
    return Optional.ofNullable(sentence)
      .filter(string -> !string.trim().isEmpty())
      .map(string -> string.split("\\s"))
      .map(Arrays::asList)
      .map(list -> Collections.max(list, Comparator.comparingInt(String::length)));
}

我们首先将句子包装成Optional,然后过滤掉所有空的和空白的String。接着,我们应用Stringsplit()方法来获取单词数组,传递"\s"作为参数,使用空格作为分隔符。然后,我们通过Arrays.asList()将数组转换为List。最后但同样重要的是,我们使用Collections.max()来获取最长的单词。这个方法有两个属性:

  • 需要确定最大值的列表
  • 用于确定最大值的比较器

在我们的例子中,我们按单词长度进行比较。我们把这个类命名为LongestWordFinder,现在我们可以对示例句子进行单元测试:

@Test
void givenAPhraseWithALongestWord_whenFindLongestWord_thenLongestWordOfThePhrase() {
    assertThat(new LongestWordFinder().findLongestWord("This is a phrase with words")).hasValue("phrase");
}

3. 找出所有最长的单词

接下来,我们将列出所有最长的单词。例如,在句子"Baeldung是这个句子中长度为八的另一个单词"中,"Baeldung"和"sentence"是两个最长的单词。

首先,我们需要处理没有单词的边缘情况,并在这种情况下返回一个空列表。同样,我们将再次将句子分割成单词数组。但是,这次我们的目标将是首先计算出最长的长度,然后使用这个长度来查找所有具有相同长度的单词:

public List<String> findLongestWords(String sentence) {
    if (sentence == null || sentence.trim().isEmpty()) {
        return Collections.emptyList();
    }
    String[] words = sentence.split("\\s");
    int maxWordLength = Arrays.stream(words)
      .mapToInt(String::length)
      .max()
      .orElseThrow();
    return Arrays.stream(words)
      .filter(word -> word.length() == maxWordLength)
      .collect(Collectors.toList());
}

如图所示,为了计算最长的长度,我们首先从单词数组创建了一个Stream。然后,我们应用了mapToInt()中间操作,将String::length作为参数。这样,我们将Stream转换成了单词长度的Stream。最后,我们获取了Stream的最大值。

总之,我们只需要过滤出具有这个最大长度的单词。我们使用另一个Stream来完成这个操作,并将匹配的单词收集到结果列表中。现在让我们检查一下findLongestWords()是否为我们的示例句子返回了预期的结果:

@Test
void givenAPhraseWithVariousWordsOfMaxLength_whenFindLongestWords_thenAllLongestsWords() {
    assertThat(new LongestWordFinder().findLongestWords("Baeldung is another word of size eight in this sentence")).containsExactly("Baeldung", "sentence");
}

4. 总结

在这篇文章中,我们将句子分割成单词列表,并使用Collections API找到了最长的单词。我们也看到了如何使用Java Stream来找到它们。如往常一样,代码可以在GitHub上找到。