如何使用 Java 流来创建一个在嵌套集合的所有元素中迭代的数组?

How can I use the Java stream in order to create an array iterating in all the element of a nested collection?

我正在开发一个 Java 应用程序,我正在尝试了解 Stream 概念是否对我的用例有用。

我正在尝试做一些类似于我在示例中发现的事情,但我的用例似乎更复杂。这是原始示例:

String[] profili = utente.getRuoli()
                 .stream().map(a -> "ROLE_" + a).toArray(String[]::new);

基本上它是从流开始创建一个数组。

按照我的情况。我有这个主要的 User DTO class 代表一个用户:

@Data
public class User {
    private int id;
    private String firstName;
    private String middleName;
    private String surname;
    private char sex;
    private Date birthdate;
    private String taxCode;
    private String eMail;
    private String pswd;
    private String contactNumber;
    private Date createdAt;
    private Set<Address> addressesList;
    private Set<UserType> userTypes;   
}

之前的 DTO class 包含表示用户类型集合的字段(例如“ADMIN”、“READER”、“WRITER”等)。这是因为一个用户可以有多种类型:

private Set<UserType> userTypes;

这是 UserType 结构:

@Data
public class UserType {
    private int id;
    private String typeName;
    private String description;
    Set<Operation> operations;
}

另外这个class包含一个表示操作集合的字段(这是因为一个用户类型可以有多个可以在系统上执行的操作),这个字段:

Set<Operation> operations;

现在我问是否可以以与原始示例类似的方式使用流,以便创建包含所有用户类型的所有操作的数组。

可能吗?什么是聪明的解决方案?或者也许最好的方法是“旧式”(将所有对象迭代到 userTypes 集合,然后将所有元素迭代到 operations 设置并手动添加到数组?)。它会工作,但使用流的简洁优雅的解决方案是什么? (如果存在)

听起来你想要的只是

userList.stream()
  .flatMap(user -> user.getUserTypes().stream())
  .flatMap(userType -> userType.getOperations().stream())
  .toArray(Operation[]::new);

...假设您正在使用吸气剂。这为您提供了针对每个用户的每个用户类型的每个操作。

对操作 Set 使用 flatMap(),使用 distinct():

Operation[] operations = user.getUserTypes().stream()
  .map(UserType::getOperations)
  .flatMap(Set::stream)
  .distinct()
  .toArray(Operation[]::new);