【问题标题】:Iterate two array lists and return with a lambda迭代两个数组列表并返回一个 lambda
【发布时间】:2018-01-20 12:56:04
【问题描述】:

我有一个方法,它有一个字符串数组列表和一个字符数组列表。我想遍历每个字符串,看看它们是否包含字符列表中的一个字符。如果不是,我想返回该字符串。我很难把它放在一个干净的 lambda 表达式中(如果可能的话)。我查看了使用 Stream 的过滤器,但我不知道是否可以使用两个 ArrayList 和一个 return 语句。

ArrayList<String> words = getWords();
ArrayList<Character> chars = getChars();
for (String word : words) {
   boolean doesNotContain = true;
   for (char letter : chars) {
      if (word.indexOf(letter) >= 0) {
         doesNotContain = false;
      }
   }
   if (doesNotContain) {
      return word;
   }
 }

【问题讨论】:

  • 您的代码示例返回第一个被“清理”的单词(不包含任何字符)。这是预期的行为,还是您真的想要获得经过净化的字词的子列表?
  • 如果没有字符串通过,你会返回什么?
  • @CostiCiudatu 是的。我在做什么是正确的。我只想要第一个字
  • @shmosel 空字符串
  • 顺便说一句,您可以通过在doesNotContain = false; 之后添加break; 来稍微提高性能。或者你可以删除变量和continue outer;。

标签: java arraylist lambda


【解决方案1】:

您可以编写一个方法来检查 String 是否包含列表中存在的任何字符,例如:

private static boolean contains(String s, ArrayList<Character> chars) {
    return s.chars()
            .filter(c -> chars.contains((char) c))
            .findAny()
            .isPresent();
}

并从您的代码中调用它以过滤掉不包含任何字符的Strings,例如:

ArrayList<String> words = new ArrayList<>();
ArrayList<Character> chars = new ArrayList<>();

List<String> filtered = words.stream()
    .filter(s -> !contains(s, chars))
    .collect(Collectors.toList());

如果你只想要第一个String,你可以使用findFirst,例如:

Optional<String> first = words.stream()
    .filter(s -> !contains(s, chars))
    .findFirst();

if(first.isPresent()){
    System.out.println(first.get());
}

【讨论】:

  • 如果我只想要第一个字符串怎么办。我应该从列表中获得第一个位置还是有更好的方法只返回一个字符串。
  • 不要将Optional 视为可空值:first.ifPresent(System.out::println)。
【解决方案2】:

这是一种方法:

return words.stream()
        .filter(word -> chars.stream().noneMatch(letter -> word.indexOf(letter) >= 0))
        .findFirst()
        .orElse("");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-14
    相关资源
    最近更新 更多