在java中从lambda forEach()返回
我试图改变一些for-each循环到lambda forEach()
方法来发现lambdaexpression式的可能性。 后继似乎是可能的:
ArrayList<Player> playersOfTeam = new ArrayList<Player>(); for (Player player : players) { if (player.getTeam().equals(teamName)) { playersOfTeam.add(player); } }
用lambda forEach()
players.forEach(player->{if (player.getTeam().equals(teamName)) {playersOfTeam.add(player);}});
但下一个没有工作:
for (Player player : players) { if (player.getName().contains(name)) { return player; } }
与lambda
players.forEach(player->{if (player.getName().contains(name)) {return player;}});
在最后一行的语法中是否有错,或者是否无法从forEach()
方法返回?
return
是从lambdaexpression式而不是从包含方法返回。 而不是forEach
你需要filter
stream:
players.stream().filter(player -> player.getName().contains(name)) .findFirst().orElse(null);
在这里, filter
将stream限制为与谓词匹配的项,然后findFirst
返回带有第一个匹配项的可选项。
这看起来不如for循环的方法,但实际上findFirst()
可能会短路 – 它不会生成整个过滤的stream,然后从中提取一个元素,而只是过滤所需的元素以find第一个匹配的。 如果你不需要从(sorting)stream中获取第一个匹配的播放器,而只需要任何匹配项,你也可以使用findAny()
而不是findFirst()
。 当涉及到平行性时,这可以提高效率。
我build议你首先尝试理解整个图片中的Java 8,最重要的是在你的情况下,它将是stream,lambdas和方法引用。
您不应该逐行将现有代码转换为Java 8代码,您应该提取function并将其转换。
我在第一个案例中确定的是:
- 如果input结构的元素匹配某个谓词,则要将其添加到输出列表中。
让我们看看我们如何做到这一点,我们可以做到以下几点:
List<Player> playersOfTeam = players.stream() .filter(player -> player.getTeam().equals(teamName)) .collect(Collectors.toList());
你在这里做的是:
- 把你的input结构变成一个stream(我在这里假设它是types的
Collection<Player>
,现在你有一个Stream<Player>
。 - 用
Predicate<Player>
过滤掉所有不需要的元素,如果希望保存,则将每个玩家映射到布尔值true。 - 通过
Collector
列表中的结果元素,在这里我们可以使用Collectors.toList()
中的标准库收集Collectors.toList()
。
这也包括另外两点:
- 针对接口进行编码,因此针对
ArrayList<E>
List<E>
进行编码。 - 在
new ArrayList<>()
使用钻石推理作为types参数,毕竟是使用Java 8的。
现在到你的第二点:
您再次想要将遗留Java的某些内容转换为Java 8,而无需查看大图。 这个部分已经被@IanRoberts回答了,不过我认为你需要对players.stream().filter(...)...
做他的build议。
这对我有什么帮助:
List<RepositoryFile> fileList = response.getRepositoryFileList(); RepositoryFile file1 = fileList.stream().filter(f -> f.getName().contains("my-file.txt")).findFirst().orElse(null);
来自Java 8在Lambda中查找列表中的特定元素
如果你想返回一个布尔值,那么你可以使用这样的事情(比过滤快得多):
players.stream().anyMatch(player -> player.getName().contains(name));