0

在我目前的项目中,我将编写一个计算平均温度的函数。

此功能的一个值得注意的点是它在不同时间接收来自多个温度源的数据。你能告诉我“我怎样才能写一个有这种行为的函数?”

例如,以下函数tempSensorData从多个温度传感器接收,这些传感器在不同时间发送温度数据。我需要编写一个计算平均温度的逻辑。

public void calculateRoomAvgTemp(TempStruct tempSensorData) {

   // Write logic of calculating Average Temperature.

}
4

5 回答 5

3

你为什么不保持一个运行平均值?假设每次读取温度读数时都会调用您的方法,您可以执行以下操作:

private final List<Double> temps = Collections
        .synchronizedList(new ArrayList<Double>());
private double currentAverage = 0d;

public void calculateRoomAvgTemp(TempStruct tempSensorData) {
    synchronized (this.temps) {
        this.temps.add(tempSensorData.temp);
        this.currentAverage = 0d;

        for (Double temp : this.temps) {
            this.currentAverage += temp;       
        }

        this.currentAverage /= this.temps.size();
    }
}
于 2012-06-22T12:44:48.383 回答
1

您可以将过去的温度存储在班级的单独字段中吗?我注意到您的方法是无效的,因此不会返回任何内容。我将假设您想将平均值存储在单独的字段中。例子:

public class TempCalculator {
    private double totalTemp = 0;
    private int sensors = 0;
    private double averageTemp = 0;

    public void calculateRoomAvgTemp(TempStruct tempSensorData) {
        totalTemp += tempSensorData.getTemp(); // Assuming getTemp() exists
        sensors += 1;
        averageTemp = totalTemp / sensors;
    }

    public double getAvgTemp() {
        return averageTemp;
    }
}

当然,如果您想存储使用的温度并根据您的需要调整形状,这可以通过列表来完成。希望这可以帮助。

于 2012-06-22T12:46:47.967 回答
1

我能想到的一种方法 - 在将值接收到 ArrayList 时将它们插入。如果您需要在收到每个数据点后计算平均温度,请运行一个 for 循环并平均 ArrayList 中的数据点以获得所需的值。可以考虑使用 memoization 来避免遍历所有值的循环。

另一种选择是使用 apache commons math,您可以使用描述性统计选项(使用滚动数组)来获得平均值(平均值)。

我假设您的代码是单线程的。如果是多线程的,您可以使用线程安全向量(或自己添加锁/同步)。希望这可以帮助。

于 2012-06-22T12:49:22.470 回答
1

要计算平均值而不将所有历史值保存在内存(或数据库)中,请使用“移动平均值”。这个数学工具可以为您提供上一个平均值加上当前值的新平均值。

于 2012-06-22T13:55:32.450 回答
0

您可以创建一个线程来计算温度,并创建许多线程来测量来自不同位置的值。完成一些测量后,线程将结果推送到例如LinkedBlockingQueue. 同步此操作很重要,因为许多线程可能会尝试同时推送结果。计算平均温度的线程将循环运行,从队列中弹出新结果,重新计算温度,然后再次尝试弹出另一个结果。只要队列为空,线程将在读取时被阻塞。这样,您将在线程之间进行异步通信,并且在测量完成后将立即重新计算平均温度。

于 2012-06-22T12:44:58.820 回答