Java 8 Lambda 按列表过滤

新手上路,请多包涵

我有两个列表,我想过滤两个列表都包含的元素。我想用 lambda 表达式来做到这一点。

用户 getName 和客户端 getUserName 都返回字符串。

这是我的示例代码:

 List<Client> clients = new ArrayList<>();
List<User> users = new ArrayList<>();
List<Client> results = new ArrayList<>();

for (Client user : users) {
    for(Client client: clients){
        if(user.getName().equals(client.getUserName())){
            result.add(client);
        }
    }
}

原文由 eszik.k 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 796
2 个回答
Predicate<Client> hasSameNameAsOneUser =
    c -> users.stream().anyMatch(u -> u.getName().equals(c.getName()));

return clients.stream()
              .filter(hasSameNameAsOneUser)
              .collect(Collectors.toList());

但这是非常低效的,因为它是 O(m * n)。您最好创建一组可接受的名称:

 Set<String> acceptableNames =
    users.stream()
         .map(User::getName)
         .collect(Collectors.toSet());

return clients.stream()
              .filter(c -> acceptableNames.contains(c.getName()))
              .collect(Collectors.toList());

另请注意,它并不严格等同于您拥有的代码(如果已编译),如果多个用户与客户端具有相同的名称,则将同一客户端两次添加到列表中。

原文由 JB Nizet 发布,翻译遵循 CC BY-SA 3.0 许可协议

看看这个:

 List<Client> result = clients
    .stream()
    .filter(c ->
        (users.stream().map(User::getName).collect(Collectors.toList())).contains(c.getName()))
        .collect(Collectors.toList());

原文由 LeoMandrak 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题