vijayashankard
vijayashankard

Reputation: 751

Java 8 stream - Referring to original stream object after flatmap

I have the following the code currently.

Method - parseGreeting()

    public GetGreetingNmsObjects parseGreeting(String greetingType, GetGreetingNmsResponse xmlFromNms) {

    GetGreetingNmsObjects objectFound = null;
    List<GetGreetingNmsObjects> objList = xmlFromNms.getObject();
    for (GetGreetingNmsObjects obj : objList) {

        List<Attribute> attrs = obj.getAttributes();
        Optional<Boolean> found = attrs.stream()
                                 .filter(a -> a.name.equals(GREETING_TYPE))
                                 .map(a -> a.value.equals(greetingType))
                                 .findAny();

        if(found.get()) {
            objectFound = obj;
            break;
        }

    return objectFound;
}

GetGreetingNmsObjects .java

public class GetGreetingNmsObjects {
    List<Attribute> attributeList;

    public List<Attribute> getAttributes() {
        return attributeList;
    } 
}

In the above method, is there a way to avoid the for loop and if statement and handle with streams itself?

I tried to use 'flatmap' and get the stream for 'attributesList' but once the match is found, I could not get reference to 'GetGreetingNmsObjects' object.

GetGreetingNmsObjects objectFound = objList.stream()
                                   .flatMap(grt -> grt.getAttributes())
                                   .filter(a -> a.name.equals(GREETING_TYPE))
                                   .map(a -> a.value.equals(greetingType))
                                   ????

Upvotes: 5

Views: 1692

Answers (1)

Holger
Holger

Reputation: 298599

Your original code contains a logic error:

Optional<Boolean> found = …
                         .map(a -> a.value.equals(greetingType))
                         .findAny();

This will return the result of an arbitrary comparison, in a sequential context, it’s likely the result of the first element.

I’m quite sure that you actually want to know whether there is any matching element, hence, should use

boolean found = …
               .anyMatch(a -> a.value.equals(greetingType));

This can be simply used as predicate to find the first element having the matching element:

return xmlFromNms.getObject().stream()
    .filter(obj -> obj.getAttributes().stream()
                      .filter(  a -> a.name.equals(GREETING_TYPE))
                      .anyMatch(a -> a.value.equals(greetingType)))
    .findFirst().orElse(null);

Upvotes: 11

Related Questions