Home > database >  How to implement Iteration over the Nested Nullable Lists using Java 8
How to implement Iteration over the Nested Nullable Lists using Java 8

Time:04-30

How can implement iteration done with multiple loops using Java 8 ?

I need to check if one of the nested objects contains the specified String i.e. "BA" or not?

if(errorEntities!=null) {
    for(ErrorEntity errorEntity : errorEntities){
        for(ErrorItemDetail errorItem : errorEntity.getErrorItem()){
            List<EntityRef> relatedEntity = errorItem.getRelatedEntity();
            if(relatedEntity!=null || !relatedEntity.isEmpty()){
                for(EntityRef entityRef : relatedEntity){
                    return entityRef.getReferredType().equalsIgnoreCase("BA");
                }
            }
        }
    }
}

CodePudding user response:

Hope this is what you were looking for:

if(errorEntities!=null) {
    return errorEntities.stream()
        .map((ErrorEntity errorEntity) -> errorEntity.getErrorItem())
        .flatMap(Collection::stream)
        .map((ErrorItemDetail errorItemDetail) -> errorItemDetail.getRelatedEntity())
        .filter((List<EntityRef> relatedEntity) -> relatedEntity == null || relatedEntity.isEmpty())
        .flatMap(Collection::stream)
        .anyMatch((EntityRef entityRef) -> entityRef.getReferredType().equalsIgnoreCase("BA"));
}

CodePudding user response:

We have 3 levels of nested lists. At the bottom of this hierarchy we have many lists of entityRefs. We are going to collects entityRefs from all of these lists into a single stream. Then we are going to see if any one of them has reference type of "BA":

return errorEntities != null && errorEntities.stream()
        .flatMap(errorEntity -> errorEntity.getErrorItem().stream())
        .map(errorItem -> errorItem.getRelatedEntity())
        .filter(relatedEntity -> relatedEntity != null)
        .flatMap(relatedEntity -> relatedEntity.stream())
        .anyMatch(entityRef -> entityRef.getReferredType().equalsIgnoreCase("BA"))

We can also do it with method references. Here we are going to create a stream of all reference type Strings in upper case. Then we are going to see if any one of them is "BA"

return errorEntities != null && errorEntities.stream()
        .map(ErrorEntity::getErrorItem)
        .flatMap(List::stream)
        .map(ErrorItemDetail::getRelatedEntity)
        .filter(Objects::nonNull)
        .flatMap(List::stream)
        .map(EntityRef::getReferredType)
        .map(String::toUpperCase)
        .anyMatch("BA"::equals));

CodePudding user response:

So you have a list of ErrorEntity and a string token ("BA").

And you need to find out whether you have at least one EntityRef object deeply nested inside the ErrorEntity that has a property that matches the token.

Judging by the code you've listed there could be null values on different levels of your collections, which isn't a good situation from the perspective of clean-coding. But you can deal with it using static method Stream.ofNullable available with Java 9 which returns an empty stream or a stream containing one element (argument that has been passed to it).

Make use of flatMap() when you need to produce a stream from a single stream element and anyMatch() to obtain a boolean value as a result.

public static boolean matches(List<ErrorEntity> source, String token) {
    return Stream.ofNullable(source) // Stream<List<ErrorEntity>>
        .flatMap(List::stream)       // Stream<ErrorEntity>
        .flatMap(errorEntity -> errorEntity.getErrorItem().stream())        // Stream<ErrorItemDetail>
        .flatMap(errorItem -> Stream.ofNullable(errorItem.relatedEntity())) // Stream<EntityRef>
        .anyMatch(entityRef -> entityRef.getReferredType().equalsIgnoreCase(token));
}

If by saying Java 8 you don't mean "Java-8 streams", but that the version you are currently using is 8, then you can make use of the method Objects.nonNull() for null-checks:

public static boolean matches(List<ErrorEntity> source, String token) {
    return Stream.of(source)                 // Stream<List<ErrorEntity>>
        .filter(Objects::isNull)
        .flatMap(List::stream)               // Stream<ErrorEntity>
        .flatMap(errorEntity -> errorEntity.getErrorItem().stream()) // Stream<ErrorItemDetail>
        .map(ErrorItemDetail::relatedEntity) // Stream<List<EntityRef>>
        .filter(Objects::nonNull)            // Stream<List<EntityRef>>
        .flatMap(List::stream)               // Stream<EntityRef>
        .anyMatch(entityRef -> entityRef.getReferredType().equalsIgnoreCase(token));
}
  • Related