重写双嵌套for循环作为Java 8流

hot*_*oup 6 java java-8 java-stream

我有以下Java方法:

public List<GrantedAuthority> toAuthorities(Set<Role> roles) {
    List<GrantedAuthority> authorities = new ArrayList<>();

    if (null != roles) {
        for (Role role : roles) {
            for (Permission permission : role.getPermissions()) {
                authorities.add(new SimpleGrantedAuthority("ROLE_" + permission.getLabel()));
            }
        }
    }

    return authorities;
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用Java 8流重写它.迄今为止我最好的尝试:

public List<GrantedAuthority> toAuthorities(Set<Role> roles) {
    List<GrantedAuthority> authorities = new ArrayList<>();

    if (null != roles) {
        roles.stream().filter(role -> ???).collect(Collectors.toList());
    }

    return authorities;
}
Run Code Online (Sandbox Code Playgroud)

但我不知道我在流过滤器中所添加的内容(替代???)......任何想法?

Nam*_*man 5

您可以使用flatMap并map替换为:

if (null != roles) {
    authorities = roles.stream()
         .flatMap(role -> role.getPermissions().stream()) // Stream<Permission>
         .map(permission -> 
                 new SimpleGrantedAuthority("ROLE_" + permission.getLabel())) // Stream<SimpleGrantedAuthority>
         .collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)

在for循环代码中,您不会根据条件过滤/过滤任何迭代并在整个列表中进行迭代,因此您不需要filter此处。


使用上面的完整方法可以写成:

public List<GrantedAuthority> toAuthorities(Set<Role> roles) {
    return roles == null ? new ArrayList<>() : roles.stream()
            .flatMap(role -> role.getPermissions().stream())
            .map(permission -> new SimpleGrantedAuthority("ROLE_" + permission.getLabel()))
            .collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)

或者按照shmosel 的建议,使用方法引用可以将其转换为:

return roles == null ? new ArrayList<>() : roles.stream()
        .map(Role::getPermissions)
        .flatMap(Collection::stream)
        .map(Permission::getLabel)
        .map("ROLE_"::concat)
        .map(SimpleGrantedAuthority::new)
        .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

  • 你可以返回`Collections.emptyList()`。 (2认同)
  • 如果你更喜欢方法引用,你可以做`roles.stream().map(Role::getPermissions).flatMap(Collection::stream).map(Permission::getLabel).map("ROLE_"::concat)。地图(SimpleGrantedAuthority::new)`。 (2认同)