1

So I have a class called station and it holds a list of readings that holds temperature, windSpeed and pressure.

What would be the nicest way of getting min/max values of temperature, windSpeed and pressure?

This is how I have done it. But I don't know it feels wrong.

public static void setMinMaxValues(Station station) {
  station.temperatureMin = station.windSpeedMin = station.pressureMin = Float.MAX_VALUE;
  for (Reading reading : station.readings) {
    if (station.temperatureMin > reading.temperature) station.temperatureMin = reading.temperature;
    if (station.temperatureMax < reading.temperature) station.temperatureMax = reading.temperature;
    if (station.windSpeedMin > reading.windSpeed) station.windSpeedMin = reading.windSpeed;
    if (station.windSpeedMax < reading.windSpeed) station.windSpeedMax = reading.windSpeed;
    if (station.pressureMin > reading.pressure) station.pressureMin = reading.pressure;
    if (station.pressureMax < reading.pressure) station.pressureMax = reading.pressure;
  }
}

I would appreciate any suggestions of how to improve it, or what could I look into to make it better.

1
  • 3
    improve it or make it better: Why? What's wrong with it? Commented May 11, 2022 at 12:10

2 Answers 2

3

You could use streaming to compute the them without an explicit loop.

public static void setMinMaxValues(Station station) {
  station.temperatureMin = station.readings.stream().mapToDouble(s -> s.temperature).min().orElse(Double.NaN);
  station.temperatureMax = station.readings.stream().mapToDouble(s -> s.temperature).max().orElse(Double.NaN);
  station.windSpeedMin = station.readings.stream().mapToDouble(s -> s.windSpeed).min().orElse(Double.NaN);
  station.windSpeedMax = station.readings.stream().mapToDouble(s -> s.windSpeed).max().orElse(Double.NaN);
  station.pressureMin = station.readings.stream().mapToDouble(s -> s.pressure).min().orElse(Double.NaN);
  station.pressureMax = station.readings.stream().mapToDouble(s -> s.pressure).max().orElse(Double.NaN);
}

Computing the values in one shot more clearly expresses intention, IMO. It also gives you better control over how to handle a lack of readings: you could use NaN as shown above, or you could leave them as OptionalDoubles, or you could decline to update the old values.

It does, however, require six passes over the readings, which is a bummer. You could reduce it to three by using summarizingDouble to compute the min and maxes of each value simultaneously.

public static void setMinMaxValues(Station station) {
  DoubleSummaryStatistics temperatureStats = station.readings.stream().collect(Collectors.summarizingDouble(s -> s.temperature));
  DoubleSummaryStatistics windSpeedStats = station.readings.stream().collect(Collectors.summarizingDouble(s -> s.windSpeed));
  DoubleSummaryStatistics pressureStats = station.readings.stream().collect(Collectors.summarizingDouble(s -> s.pressure));

  station.temperatureMin = temperatureStats.getMin();
  station.temperatureMax = temperatureStats.getMax();
  station.windSpeedMin = windSpeedStats.getMin();
  station.windSpeedMax = windSpeedStats.getMax();
  station.pressureMin = pressureStats.getMin();
  station.pressureMax = pressureStats.getMax();
}

If there are no readings this will assign +∞ to the mins and -∞ to the maxes.

Sign up to request clarification or add additional context in comments.

Comments

0

Check out the Math Class. You can e. g. replace

if (station.temperatureMin > reading.temperature) station.temperatureMin = reading.temperature;

with

station.temperatureMin = Math.min(station.temperatureMin, reading.temperature);

There of course is a Math.max() as well

Comments

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.