Java8流API中的条件检查
我有以下现有的实现
CompletableFuture<Employee>[] employeeDetails =
empIds.stream().map(empId ->
employeeService.employeeDetails(Integer.valueOf(empId)))
.filter(Objects::nonNull)
.toArray(CompletableFuture[]::new);
在这段代码中,我需要在HashMap中检查empId是否已经存在,如下所示——如果empId在HashMap中不存在,则调用服务并将其放入HashMap中以备将来使用
Map<String, CompletableFuture<Employee>[]> employeeCache = new HashMap<>();
..........
CompletableFuture<Employee>[] employeeDetails =
empIds.stream().map(empId ->
//Here I need to check in HashMap that empId is present or not if present then fetch from Map instead of calling service.
employeeService.employeeDetails(Integer.valueOf(empId)))
.filter(Objects::nonNull)
.toArray(CompletableFuture[]::new);
如何添加if
签入stream()
api,如上图所示,如果存在,则从Map获取
# 1 楼答案
你可以使用^{} 来实现你想要做的事情:
# 2 楼答案
如果您不再需要
employeeCache
映射,也就是说,如果您只将其用作Stream.map
操作中的本地缓存,则可以通过通用实用程序方法将其提取出来:这被称为memoization,是一种众所周知的技术,尤其是在函数式编程中
然后,在示例中使用它,如下所示:
正如您所看到的,这对调用方代码是完全透明的,它确实会将映射用作缓存
编辑:请注意,我只使用了一个公共的^{,因为我注意到流是按顺序运行的。如果要并行运行流,应该将缓存更改为
ConcurrentHashMap
# 3 楼答案
您可以在} (因为} (在
Stream.map
操作中使用^{Map
中缺少键将返回null
)和^{Map
中不存在值时进行服务调用),如下所示:或者正如Aomine在评论中所建议的,您也可以简单地使用
getOrDefault
:如果你也想放入缓存,你可以简单地使用^{} 来放入,如果不存在的话:如果您想在从服务中删除内容的同时也更新缓存,您最好在此处不使用流:
此外,所有这些(如果我是你的话)我都会使用Guava的^{} ,它甚至可以通过定制的
CacheLoader
实现在封面下提供类似的好处关于它的更多细节,你可以阅读他们的维基-CachesExplained