Home > Enterprise >  How to use stream not multiple foreach?
How to use stream not multiple foreach?

Time:07-06

I have this two methods:

for (RuntimeProductOfferEntity productOfferEntity : eligibleOffers) {
            if (productOfferEntity.getSalesSubCategory().equalsIgnoreCase(nonBillable.getSubCategory())
                    && Boolean.TRUE.equals(filterByCharacteristcs(productOfferEntity, nonBillable.getDuration().toString()))) {
                productOffers.add(ProductOfferResponse.builder().categoryId(nonBillable.getCategoryId())
                        .offerCode(productOfferEntity.getCode()).build());

            }
        }

And my method where i user foreach:

private Boolean filterByCharacteristcs(final RuntimeProductOfferEntity offer, final String duration) {
        for (RuntimeTemplateEntity template : offer.getTemplates()) {
            for (RuntimeCharacteristicEntity charateristic : template.getCharacteristics()) {
                if ("VARIJACIJA".equalsIgnoreCase(charateristic.getCode())) {
                    for (RuntimeCharacteristicValueEntity value : charateristic.getCharacteristicValues()) {
                        if (duration.equalsIgnoreCase(value.getValue())) {
                            return Boolean.TRUE;
                        }
                    }
                }
            }

        }
        return Boolean.FALSE;

    }

Is there any way to use stream and not to use this multiple foreach?

CodePudding user response:

Not tested, but probably something like this :

private boolean filterByCharacteristcs(final RuntimeProductOfferEntity offer, final String duration) {
    return offer.getTemplates()
        .stream()
        .flatMap(template -> template.getCharacteristics().stream())
        .filter(characteristic -> "VARIJACIJA".equals(characteristic.getCode()))
        .flatMap(characteristic -> characteristic.getCharacteristicValues().stream())
        .anyMatch(value -> duration.equalsIgnoreCase(value.getValue()));
}

The flatMap is used to flatten the data. Example (pseudo code): [{values: [2, 3]}, {values: [4, 5]}].flatMap(x -> x.getValues().stream()) => [2, 3, 4, 5]

For the first stream, it works if getTemplates() returns a collection. If it's an Iterable, see Convert Iterable to Stream using Java 8 JDK

The first part will just convert your templates to a stream of characteristics by converting stream of objects to a stream of nested objects. Then use anyMatch to just check if one of the value matches the condition, no matter which one.

  •  Tags:  
  • java
  • Related