[英]Rewrite double nested for loop as a Java 8 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;
}
我正在嘗試使用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;
}
但我不知道我在流過濾器中放了什么(代替???
)......任何想法?
你可以使用flatMap
和map
instaead來做到:
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());
}
在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());
}
或者如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());
你可以在一個鏈中做到這一點,但不確定你的可讀性如何:
public static List<GrantedAuthority> toAuthorities(Set<Role> roles) {
return Optional.ofNullable(roles)
.orElse(Collections.emptySet())
.stream()
.flatMap(r -> r.getPermissions().stream())
.map(Permission::getLabel)
.map("ROLE_"::concat)
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.