从java中的lambda foreach()返回

kr98yfug  于 2021-07-12  发布在  Java
关注(0)|答案(5)|浏览(371)

我正在尝试将一些for each循环更改为lambda forEach() -方法来发现lambda表达式的可能性。以下似乎是可能的:

ArrayList<Player> playersOfTeam = new ArrayList<Player>();      
for (Player player : players) {
    if (player.getTeam().equals(teamName)) {
        playersOfTeam.add(player);
    }
}

和兰姆达在一起 forEach() ```
players.forEach(player->{if (player.getTeam().equals(teamName)) {playersOfTeam.add(player);}});

但下一个不起作用:

for (Player player : players) {
if (player.getName().contains(name)) {
return player;
}
}

和兰姆达在一起

players.forEach(player->{if (player.getName().contains(name)) {return player;}});

最后一行的语法有什么错误吗?还是无法从中返回 `forEach()` 方法?
u7up0aaq

u7up0aaq1#

这个 return 从lambda表达式返回而不是从包含方法返回。而不是 forEach 你需要 filter 溪流:

players.stream().filter(player -> player.getName().contains(name))
       .findFirst().orElse(null);

在这里 filter 将流限制为与 predicate 匹配的项,并且 findFirst 然后返回 Optional 第一个匹配的条目。
这看起来比for-loop方法效率低,但实际上 findFirst() 可以短路-它不会生成整个过滤流,然后从中提取一个元素,而是只过滤所需的元素,以便找到第一个匹配的元素。你也可以用 findAny() 而不是 findFirst() 如果您不一定关心从(订购的)流中获取第一个匹配的播放器,只关心任何匹配项。当涉及到并行性时,这可以提高效率。

2g32fytz

2g32fytz2#

我建议您首先尝试从整体上理解Java8,最重要的是在您的情况下,它将是流、lambda和方法引用。
您不应该逐行将现有代码转换为Java8代码,您应该提取特性并转换这些特性。
我在你的第一个案例中确认了以下内容:
如果输入结构的元素与某个 predicate 匹配,则需要将其添加到输出列表中。
让我们看看如何做到这一点,我们可以通过以下方法做到:

List<Player> playersOfTeam = players.stream()
    .filter(player -> player.getTeam().equals(teamName))
    .collect(Collectors.toList());

你在这里做的是:
将您的输入结构转换为流(我在这里假设它是 Collection<Player> ,现在你有了 Stream<Player> .
用滤纸过滤掉所有不需要的元素 Predicate<Player> ,如果希望保留,则将每个播放器Map到布尔值true。
通过 Collector ,这里我们可以使用一个标准库收集器 Collectors.toList() .
这还包括另外两点:
针对接口编写代码,因此针对 List<E> 结束 ArrayList<E> .
对中的类型参数使用菱形推断 new ArrayList<>() ,您使用的毕竟是Java8。
现在谈谈你的第二点:
您再次希望将遗留的java转换为java8,而不必考虑全局。这部分已经被@ianroberts回答了,不过我认为你需要这样做 players.stream().filter(...)... 他建议的事。

92dk7w1h

92dk7w1h3#

如果您想返回一个布尔值,那么您可以使用这样的方法(比filter快得多):

players.stream().anyMatch(player -> player.getName().contains(name));
wdebmtf2

wdebmtf24#

这对我有帮助:

List<RepositoryFile> fileList = response.getRepositoryFileList();
RepositoryFile file1 = fileList.stream().filter(f -> f.getName().contains("my-file.txt")).findFirst().orElse(null);

摘自Java8,使用lambda查找列表中的特定元素

9vw9lbht

9vw9lbht5#

也可以引发异常:

注:

为了可读性,流的每一步都应该列在新行中。

players.stream()
       .filter(player -> player.getName().contains(name))
       .findFirst()
       .orElseThrow(MyCustomRuntimeException::new);

如果您的逻辑是松散的“异常驱动”,比如代码中有一个地方可以捕获所有异常并决定下一步要做什么。只有在可以避免代码库中出现多个错误的情况下,才可以使用异常驱动的开发 try-catch 抛出这些异常是针对您期望的非常特殊的情况,并且可以正确处理。)

相关问题