首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java :收集一个长流的复杂性是否与基于Set::contains对其进行过滤相同?

Java :收集一个长流的复杂性是否与基于Set::contains对其进行过滤相同?
EN

Stack Overflow用户
提问于 2021-03-02 20:34:13
回答 2查看 178关注 0票数 1

我有一个应用程序,它接受员工I作为用户输入,然后筛选员工列表以匹配I。用户输入应该是3-4个is,员工列表是几千个。

我提出了以下两种基于性能考虑使用流过滤器的方法。

Method1

这里的

动机不是为每个员工运行过滤器,而是在请求的ids列表上运行它,这保证非常短。

代码语言:javascript
复制
private static Set<Long> identifyEmployees(CustomRequest request)
  List<Long> requestedIds = request.getRequestedIDs();                            
  if (!requestedIds.isEmpty()) {
      Set<Long> allEmployeeIds = 
              employeeInfoProvider
                .getEmployeeInfoList()  // returns List<EmployeeInfo>
                .stream()
                .map(EmployeeInfo::getEmpId)  // getEmpId() returns a Long
                .collect(Collectors.toSet());

      return requestedIds.stream().filter(allEmployeeIds::contains).collect(Collectors.toSet());         
  }
  return Collections.emptySet();
}

Method2

这里的

动机是将Method1中的collect()替换为一个过滤器,因为复杂性是相同的。这里的collect()实际上是在极少数元素上运行的。

代码语言:javascript
复制
private static Set<Long> identifyEmployees(CustomRequest request)
  Set<Long> requestedIds = request.getRequestedIDs()   // returns List<Long>
                          .stream()
                          .collect(Collectors.toSet());
  if (!requestedIds.isEmpty()) {
      return employeeInfoProvider
               .getEmployeeInfoList()  // returns List<EmployeeInfo>
               .stream()
               .map(EmployeeInfo::getEmpId)  // getEmpId() returns a Long
               .filter(requestedIds::contains)
               .collect(Collectors.toSet());
  }
  return Collections.emptySet();
}

Method2的表现和Method1一样好吗?还是Method1表现得更好?

EN

回答 2

Stack Overflow用户

发布于 2021-03-02 20:50:36

我希望Method2在所有场景中都表现良好或更好。

收集到中间集会增加分配开销。如果有大量的重复,它减少了以后必须执行的requestedIds::contains调用的数量,但是即使这样,您也要将每个Set::add调用交换为一个Set::contains调用,每个调用都应该是一个小胜利。

票数 2
EN

Stack Overflow用户

发布于 2021-03-02 21:02:05

一个可能更快(而不是更干净)的选项是在检测到所有requestedIds后立即返回,但我不确定它是否可以用Stream实现。

代码语言:javascript
复制
private static Set<Long> identifyEmployees(CustomRequest request) {
    Set<Long> requestedIds = request.getRequestedIDs()   // returns List<Long>
            .stream()
            .collect(Collectors.toSet());
    Set<Long> result = new HashSet<>();
    if (!requestedIds.isEmpty()) {
        Iterator<EmployeeInfo> employees = employeeInfoProvider.getEmployeeInfoList().iterator();
        while (result.size() < requestedIds.size() && employees.hasNext()) {
            Long employeeId = employees.next().getEmpId();
            if (requestedIds.contains(employeeId)) {
                result.add(employeeId);
            }
        }
    }
    return result;
}

但是,只有当employeeInfoProvider.getEmployeeInfoList()返回具有相同ID的多个员工副本时,才有意义。否则,如上所述,method2是一个更好的选择。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66446731

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档