如何在流运算符的帮助下填写集合中的属性



我有两个类型为Builder的对象生成器和类型为AdminUser的adminUsers的列表。

以下是类的类型防御:

public class Builder {
@Id
private String id;
private String name;
@Field("company_name")
private String companyName;
@Indexed(unique=true)
private String email;
private UserRole userRole;
}
public class AdminUser {
@Id
private String id;
@Indexed(unique=true)
private String email;
private List<GrantedAuthority> authorities;
}
public enum UserRole {
ROLE_ADMIN,
ROLE_DATA,
ROLE_BUILDER
}

我尝试填充builders集合的名为UserRole的属性具有来自builders集合中每个项的adminUser集合的UserRole属性。

以下是我如何以命令的态度做到这一点:

List<Builder> builders = builderRepository.findAllBy();
List<AdminUser> adminUsers = adminUserRepository.findAllBy();
for (Builder builder : builders) {
for (AdminUser adminUser : adminUsers) {
if (builder.getEmail().equals(adminUser.getEmail()))
builder.setUserRole(UserRole.valueOf(adminUser.getAuthorities().get(0).getAuthority()));
}
}

上面的代码有效。

我试图用流运算符的声明性态度来实现这一点。但我感到困惑,最后用古老的命令式写了出来。你能帮我看一个例子,说明如何在流和中间运算符的帮助下,以声明的方式编写上面的代码吗?

流可以用于过滤、转换或其他操作。通常,一个或多个集合会转换为其他集合,或者更改集合的大小。但是,在您的示例中,没有集合转换或大小更改。最多可以将示例中的for循环替换为forEach,但这没有意义。

当Builders和AdminUsers的数量较大时,此代码的复杂性为O(n^2(。您可以使用哈希来降低复杂性。

Map<String, String> emailAuthMap = adminUsers.stream()
.collect(Collectors.toMap(AdminUser::getEmail, u -> u.getAuthorities().size() > 0 ? u.getAuthorities().get(0).getAuthority() : null));
for (Builder builder : builders) {
String auth = emailAuthMap.get(builder.getUserRole());
builder.setUserRole(auth != null ? UserRole.valueOf(auth) : null);
}

最新更新