CHARAFI Saad
CHARAFI Saad

Reputation: 1440

JAVA 8 : Change value inside stream

I have a list of objects and I loop on every element of this list and I modify several attributes.

Here is my code that I want to transform to use the stream API.

        for (Besoin besoin : besoins) {
        String purchaseOrderPosition = besoin.getReferenceOa().trim();
        if(purchaseOrderPosition != "") {
            ValeursDynamiques valeursDynamiques = valeursDynamiquesService.DynamicValues(supplierNumber, purchaseOrderPosition);
            besoin.setQuantityInTransit(valeursDynamiques.getUsedValues().getQteEnTransit());
            besoin.setQuantityOrdered(valeursDynamiques.getUsedValues().getQteCommandee());
            besoin.setQuantityDelivered(valeursDynamiques.getUsedValues().getQteRecue());
            besoin.setDeliveryDateScheduled(valeursDynamiques.getUsedValues().getDateLivraisonPlanifiee());
            besoin.setDeliverydateConfirmed(valeursDynamiques.getUsedValues().getDateLivraisonConfirmee());
            besoin.setQuantityRestExpedited(valeursDynamiques.getUsedValues().getSoldeAExpedier());
        }   
    }

Upvotes: 4

Views: 2935

Answers (2)

user43968
user43968

Reputation: 2129

This should be corrrect since you aren't modifiying the list but the attribut of the element :

    besoins.stream().forEach(besoin -> {
    String purchaseOrderPosition = besoin.getReferenceOa().trim();
    if(!purchaseOrderPosition.isEmpty()) {
        ValeursDynamiques valeursDynamiques = valeursDynamiquesService.DynamicValues(supplierNumber, purchaseOrderPosition);
        besoin.setQuantityInTransit(valeursDynamiques.getUsedValues().getQteEnTransit());
        besoin.setQuantityOrdered(valeursDynamiques.getUsedValues().getQteCommandee());
        besoin.setQuantityDelivered(valeursDynamiques.getUsedValues().getQteRecue());
        besoin.setDeliveryDateScheduled(valeursDynamiques.getUsedValues().getDateLivraisonPlanifiee());
        besoin.setDeliverydateConfirmed(valeursDynamiques.getUsedValues().getDateLivraisonConfirmee());
        besoin.setQuantityRestExpedited(valeursDynamiques.getUsedValues().getSoldeAExpedier());
    }   
}

you can directly use forEach() from list, and I have use the isEmpty() intead of != "".

But as previously stated why use a Stream here ? besoins.stream().forEach(besoin -> is less readable than for (Besoin besoin : besoins)

In general when prefer stream to filter, map, and extract some data

Upvotes: 2

Eugene
Eugene

Reputation: 120848

Modifying the elements from the source of the stream is not a structural change of the source per-se. Yes, you can do it, even in parallel this will not fail. But it's hardly the point streams where made for; unless you have other operations that you might need (filter, map, etc) your loop makes a lot more sense.

For example ArrayList documentation says:

... merely setting the value of an element is not structural modification

As such your code that modifies an element, but not the source of the stream (List in your case) will not throw ConcurrentModificationException.

Upvotes: 1

Related Questions