我正在尝试将一些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()` 方法?
5条答案
按热度按时间u7up0aaq1#
这个
return
从lambda表达式返回而不是从包含方法返回。而不是forEach
你需要filter
溪流:在这里
filter
将流限制为与 predicate 匹配的项,并且findFirst
然后返回Optional
第一个匹配的条目。这看起来比for-loop方法效率低,但实际上
findFirst()
可以短路-它不会生成整个过滤流,然后从中提取一个元素,而是只过滤所需的元素,以便找到第一个匹配的元素。你也可以用findAny()
而不是findFirst()
如果您不一定关心从(订购的)流中获取第一个匹配的播放器,只关心任何匹配项。当涉及到并行性时,这可以提高效率。2g32fytz2#
我建议您首先尝试从整体上理解Java8,最重要的是在您的情况下,它将是流、lambda和方法引用。
您不应该逐行将现有代码转换为Java8代码,您应该提取特性并转换这些特性。
我在你的第一个案例中确认了以下内容:
如果输入结构的元素与某个 predicate 匹配,则需要将其添加到输出列表中。
让我们看看如何做到这一点,我们可以通过以下方法做到:
你在这里做的是:
将您的输入结构转换为流(我在这里假设它是
Collection<Player>
,现在你有了Stream<Player>
.用滤纸过滤掉所有不需要的元素
Predicate<Player>
,如果希望保留,则将每个播放器Map到布尔值true。通过
Collector
,这里我们可以使用一个标准库收集器Collectors.toList()
.这还包括另外两点:
针对接口编写代码,因此针对
List<E>
结束ArrayList<E>
.对中的类型参数使用菱形推断
new ArrayList<>()
,您使用的毕竟是Java8。现在谈谈你的第二点:
您再次希望将遗留的java转换为java8,而不必考虑全局。这部分已经被@ianroberts回答了,不过我认为你需要这样做
players.stream().filter(...)...
他建议的事。92dk7w1h3#
如果您想返回一个布尔值,那么您可以使用这样的方法(比filter快得多):
wdebmtf24#
这对我有帮助:
摘自Java8,使用lambda查找列表中的特定元素
9vw9lbht5#
也可以引发异常:
注:
为了可读性,流的每一步都应该列在新行中。
如果您的逻辑是松散的“异常驱动”,比如代码中有一个地方可以捕获所有异常并决定下一步要做什么。只有在可以避免代码库中出现多个错误的情况下,才可以使用异常驱动的开发
try-catch
抛出这些异常是针对您期望的非常特殊的情况,并且可以正确处理。)