Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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))
                                   ????
like image 758
vijayashankard Avatar asked Jan 20 '17 11:01

vijayashankard


People also ask

Do streams modify original list?

That means list. stream(). filter(i -> i >= 3); does not change original list. All stream operations are non-interfering (none of them modify the data source), as long as the parameters that you give to them are non-interfering too.

How do you use flatMap in stream?

We can use a flatMap() method on a stream with the mapper function List::stream. On executing the stream terminal operation, each element of flatMap() provides a separate stream. In the final phase, the flatMap() method transforms all the streams into a new stream.

Does flatMap preserve order Java?

Does flatmap() method preserve the order of the streams? Yes, It does and map() also.

How do I add an element to an existing stream in Java?

One approach is to use a terminal operation to collect the values of the stream to an ArrayList, and then simply use add(int index, E element) method. Keep in mind that this will give you the desired result but you will also lose the laziness of a Stream because you need to consume it before inserting a new element.


1 Answers

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);
like image 88
Holger Avatar answered Oct 04 '22 00:10

Holger