java stream contains 代码效率优化

/ 默认分类 / 没有评论 / 14浏览
List<String> userIdList= refers.stream().filter(r -> Objects.equals(r.getAppCode(), f)).collect(Collectors.toList()).stream().map(AdReferVo::getUserId).collect(Collectors.toList());
List<LogAdVo> logs = logAds.stream().filter(t -> !userIds.contains(t.getUserId())).collect(Collectors.toList());

当上面第一步收集到list,然后在log判断 userIdList.contains("xxx")时,会产生很大的效率问题,由于log的数据量很大,当执行filter的时候,每个log都需要进行一次contain,而每个contain又会对userIdList遍历,也就是时间复杂度为 O(n), 而整个系统的时间复杂度就是O(n²),会极大拖累系统的执行效率,上述代码在生产中百万级数据量耗时大概在10分钟。

现在优化页很简单,只需要把第一句修改为set数据结构,这样contain的时间复杂度就变成了O(1),系统整体时间复杂度就变成了O(n) 优化后如下:

Set<String> userIdList= refers.stream().filter(r -> Objects.equals(r.getAppCode(), f)).collect(Collectors.toList()).stream().map(AdReferVo::getUserId).collect(Collectors.toSet());

百万级数据时间约为5秒,当然还有其他一些逻辑在,这里省略