Переписать двойное гнездо для цикла как поток Java 8 - PullRequest
0 голосов
/ 25 октября 2018

У меня есть следующий метод 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;
}

Но я в растерянности относительно того, что я положил в фильтр потоков (заменяя ???) ... какие-нибудь идеи?

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Вы можете сделать это в одной цепочке, хотя вы не уверены, насколько это читабельно:

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());
}
0 голосов
/ 25 октября 2018

Вы можете сделать это, используя 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());
...