Keshtocal
Keshtocal

Reputation: 162

Java Stream: Merge value of list with values of nested list to one list

I have the following classes:

@Setter
@NoArgsConstructor
public classAccount {
    List<AccountRole> accountRoles = new ArrayList<>();    
    List<AccountRole> getAccountRoles() { return accountRoles };
}
    
@Setter
@NoArgsConstructor
public class AccountRole {
    List<Operation> operations = new ArrayList<>();
    List<Operation> getAllowedOperations( return operations);
    String accountRole;
    String getAuthority() { return accountRole; }
}
    
@Setter
@NoArgsConstructor
public class Operation {
    String operation;
    String getAuthority( return operation; )
}

I managed it to collect all authorities of the operations like:

account.getAccountRoles().stream()
    .flatMap(accountRole -> accountRole.getAllowedOperations().stream().map(operation -> operation.getAuthority()))
    .collect(Collectors.toList())

I didn't manage it to collect the authorities of account roles and the operations in one stream and merge them to the result list. Is there a possibility?

Upvotes: 0

Views: 1265

Answers (2)

OrangeDog
OrangeDog

Reputation: 38777

You can do this with Stream.concat:

Creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream.

account.getAccountRoles().stream()
    .flatMap(role -> Stream.concat(
            role.getAllowedOperations().stream().map(Operation::getAuthority),
            Stream.of(role.getAuthority())))
    .collect(Collectors.toList())

Unless you're doing something more complex than just putting them all in a list, then it's probably better to not build a combined stream. Just independently add them to a list:

List<String> result = new ArrayList<>();
for (AccountRole role : account.getAccountRoles()) {
    for (Operation operation : role.getAllowedOperations()) {
        result.add(operation.getAuthority());
    }
    result.add(role.getAuthority();
}

Upvotes: 2

Youcef LAIDANI
Youcef LAIDANI

Reputation: 59978

You can use :

        .flatMap(accountRole -> {
                    List<String> roles = accountRole.getAllowedOperations().stream()
                            .map(Operation::getAuthority)
                            .collect(Collectors.toList());
                    roles.add(accountRole.getAuthority());
                    return roles.stream();
                }
        )

You can also create a method to get roles as this :

private Stream<String> getRoles(AccountRole accountRole) {
    List<String> roles = accountRole.getAllowedOperations().stream()
            .map(Operation::getAuthority)
            .collect(Collectors.toList());
    roles.add(accountRole.getAuthority());
    return roles.stream();
}

and then, you can just call :

.flatMap(this::getRoles)

Upvotes: 1

Related Questions