1

There is a Waybill object that has a Set<Packing> field, the Packing object has a PRICE field. I get a List<Waybill>. Need to calculate the total cost of all Packing from the entire List<Waybill>. How it competently to make through Stream? Thank you.

class Waybill {
    Set<Packing> setOfPacking;
}

class Packing {
    int PRICE;
}

List<Waybill> allWaybills = ...
3
  • To clarify, by "Stream" are you referring to Java's Stream API - the Java equivalent of .NET's Linq, or do you mean an actual java.io.Stream object you must deserialize from? Commented Sep 13, 2017 at 23:52
  • @Dai Yes, I mean java.io.Stream Commented Sep 13, 2017 at 23:54
  • @Denis - I think you mean java.util.stream.Stream<T> Commented Sep 14, 2017 at 0:00

2 Answers 2

3

This worked for me:

double total = allWaybills.stream()
    .flatMap(waybill -> waybill.setOfPacking.stream())
    .mapToInt(packing -> packing.PRICE)
    .sum();

I think it is easier to reason about because there aren't any multi-level stream operations.

I would be interested to see how to use flatMapToInt to replace both the flatMap and map operations with one operation without making it multi-level.

Here is a test program:

import java.util.Set;
import java.util.List;
import java.util.HashSet;
import java.util.ArrayList;
import java.util.stream.Collectors;

public class HelloWorld
{
    public static class Packing
    {
        public int PRICE = 0;
    }

    public static class Waybill
    {
        public Set<Packing> setOfPacking = new HashSet<Packing>();
    }

    public static void main(String []args){
        List<Waybill> allWaybills = new ArrayList<Waybill>();

        Waybill w1 = new Waybill();
        Packing p1 = new Packing(); p1.PRICE = 1; w1.setOfPacking.add(p1);
        Packing p2 = new Packing(); p2.PRICE = 2; w1.setOfPacking.add(p2);
        allWaybills.add(w1);

        Waybill w2 = new Waybill();
        Packing p3 = new Packing(); p3.PRICE = 3; w2.setOfPacking.add(p3);
        Packing p4 = new Packing(); p4.PRICE = 4; w2.setOfPacking.add(p4);
        allWaybills.add(w2);

        double total = allWaybills.stream()
            .flatMap(waybill -> waybill.setOfPacking.stream())
            .mapToInt(packing -> packing.PRICE)
            .sum();

        System.out.println("total = "+total);
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! But tell me please, what is the difference? The better flatMap ()?
@Denis I just think it is easier to understand because it isn't nested. Probably from the JVM's point of view it is exactly the same. Which one do you find easier to understand?
I understand both, and another) Interesting implementation is different, thank you for reacting so quickly!
0
import java.util.stream.*

List<Waybill> allWaybills = ...
int totalCost = allWaybills
    .stream()
    .mapToInt(w -> w.setOfPacking
        .stream()
        .mapToInt(p -> p.PRICE)
        .sum()
    )
    .sum();

1 Comment

I think you can optimise this with flatMapToInt() (should be able to remove one sum).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.