简体   繁体   中英

How can I use Java Stream in order to iterate on a collection on object and use a specific string field of each object to create a new array?

I am not so into Java Stream and I have the following problem.

I am generating a JWT token in this way. The JWT token generation it is only the context on which I am working on but it is not strictly related to my problem. My problem is related about how to create a list of Strings from a specific field of n objects into a Set.

So I have the following situation:

I have this User object:

@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;

}

As you can see it contains the Set<UserType> userTypes field, representing a collection of possible user types (basically the user profiles such as "ADMIN", "READER", MODERATOR", this because in my system a single user can have multiple user types).

And this is the UserType definition:

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

So basically the interested field is the typeName . Starting from a Set<UserType> userTypes I have to obtain a List of String, something like: **["ADMIN", "READER", "SIMPLE_USER"] where the array object is the value of the typeName field.

Into my code I have this method:

private String doGenerateToken(Map<String, Object> claims, UserDetailsWrapper userDetailsWrapper) {
    final Date createdDate = clock.now();
    final Date expirationDate = calculateExpirationDate(createdDate);
    
    // MOCKED USER PROFILES COLLECTION:
    ArrayList<String> userProfiles = new ArrayList<String>();
    userProfiles.add("SIMPLE_USER");
    userProfiles.add("MODERATOR");
    

    return Jwts.builder()
            .setClaims(claims)
            .setSubject(userDetailsWrapper.getUserDetails().getUsername())
            .claim("name", userDetailsWrapper.getUserCompleteInfo().getFirstName() + " " 
                         + userDetailsWrapper.getUserCompleteInfo().getMiddleName() + " "
                         + userDetailsWrapper.getUserCompleteInfo().getSurname())
            .claim("user_profiles", userProfiles)
            //.claim("user_profiles", userDetailsWrapper.getUserCompleteInfo().getUserTypes().stream().map(UserType::getUserType).collect(Collectors.toList()))
            .claim("authorities", userDetailsWrapper.getUserDetails().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()))
            .setIssuedAt(createdDate)
            .setExpiration(expirationDate)
            .signWith(SignatureAlgorithm.HS512, jwtConfig.getSecret().getBytes())
            .compact();
}

As you can see in the previous code snippet I have mocked the userProfiles ArrayList, then I am adding it to my JWT token payload by:

.claim("user_profiles", userProfiles)

It works fine. The problem is that I have to do the same thing starting from the collection returned by (this is the previous mentioned Set<UserType> userTypes field):

userDetailsWrapper.getUserCompleteInfo().getUserTypes()

Basically I need a way to use Java Stream to iterate on this collection and then add the typeName field (that is a String) of each object into the array used by the claim() method as input parameter.

In the previous code you can find (commented out) an attempt that I have done but Eclipse give me error so it is wrong.

How can I try to implement this behavior using Java Stream?

.claim("user_profiles",userDetailsWrapper.getUserCompleteInfo()
.getUserTypes().stream()
.map(UserType::getTypeName)
.collect(Collectors.toList()))

You should call map function to get typeName from UserType object. Try above code please

You are trying to convert to the wrong type

.claim("user_profiles", userDetailsWrapper.getUserCompleteInfo()
    .getUserTypes()
    .stream()
    // Convert each UserType to a String using the getter for typeName field
    .map(UserType::getTypeName) 
    // Create a list from the Stream of TypeName strings
    .collect(Collectors.toList()))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM