How to get an average of type int from a stream of int?

Paglie98 :

I'm writing a program in which I have to get the average delay for trains, but I'm having trouble as the stream must return an int (which means it will approximate the value). I'd prefer not to use a downcast. The following is a code example

public int getAvgDelay(){
  return trainStop.stream()
                  .flatMapToInt(a->a.getDelays().stream())
                  .average().orElse(-1);
}

getDelays() returns a List of Integers with the delays for that train in a single station, I convert it to a stream, then the average will return a double, but I want to find a way to get an Int out of it.

Overall I'm having trouble with most streams where I have to return a single value after using some summarizing collectors, if you could give me a general rule on how to do it I would really appreciate it!

Samuel Philipp :

This is one method using Math.round() to round the average value and cast it to an int:

public int getAvgDelay() {
    return trainStop.stream()
            .flatMapToInt(a -> a.getDelays().stream())
            .average().stream()
            .mapToLong(Math::round).mapToInt(i -> (int) i)
            .findFirst().orElse(-1);
}

But you should consider to return an Optional instead of a magic number (-1). If you do so you also can return the OptionalDouble or if you want a whole number an OptionalLong directly to prevent casting to an int.

You then can call your method like this:

int avg = getAvgDelay().orElse(-1);

Or use .orElseThrow() if you need an error state.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=142528&siteId=1