3

I have this class:

public class StructUserType extends UserType {

    MembersList membersList = new MembersList();

    public List<Member> getMembers() {
        return Collections.unmodifiableList(membersList.members);
    }

    static class MembersList {
        List<Member> members = new ArrayList<>();
    }

    public static class Member implements Identifiable {
        private Integer id;

        public Integer getId() {
            return id;
        }
    }    
} 

And I have a List object:

List<SmbpUserType> userTypes = new ArrayList<>();

I want find Member which is equal to a certain id. I tried as follows:

Integer id = 1;
userTypes.stream()
                .filter(StructUserType.class::isInstance)
                .map(StructUserType.class::cast)
                .forEach(structUserType -> {
                    structUserType.getMembers()
                            .stream()
                            .filter(m -> m.getId() == id)
                            .findFirst().orElse(null);
                });

I want, when the filter in the internal stream runs and finds the first member, to return the parent element that this member contains, those UserType.

Analog in the classical style:

for (UserType userType : userTypes) {
            if (userType instanceof StructUserType) {
                List<StructUserType.Member> members = ((StructUserType) userType).getMembers();

                for (StructUserType.Member member : members) {
                    if (member.getId() == id) {
                        return userType;
                    }
                }
            }
        }
        return null;

2 Answers 2

6

Replace forEach with filter, to find StructUserType instances that satisfy the condition of the inner stream pipeline. Then get the first element of the Stream, if such exists.

return
   userTypes.stream()
            .filter(StructUserType.class::isInstance)
            .map(StructUserType.class::cast)
            .filter(st -> st.getMembers()
                            .stream()
                            .anyMatch(m -> m.getId().equals(id)))
            .findFirst()
            .orElse(null);
Sign up to request clarification or add additional context in comments.

1 Comment

This is a perfect opportunity to return an Optional<T> rather than the value if present else null. This will document to the user of this method that there may or may not be a value present therefore they can use the Optional<T> methods to safely get the value if present.
3

Instead of forEach you can use a filter for the nested Stream.

At last you can return the first match or collect all matches

...
.filter(structUser -> structUser.getMembers()
                      .stream()
                      .anyMatch(member -> member.getId().equals(id))
       )
...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.