0

次のようなファイルを解析するJavaクラスを作成しています。

[thread 16] INFO - L3: createOrder: min [239.0] max [1245.0] average [488.06]  
[thread 16] INFO - L3: translateBarCode: min [9.0] max [132.0] average [31.1]  
[thread 11] INFO - L3: createOrder: min [258.0] max [2458.0] average [506.31]  
[thread 13] INFO - L3: createOrder: min [243.0] max [1303.0] average [542.57]  
[thread 11] INFO - L3: translateBarCode: min [9.0] max [104.0] average [29.79] 
[thread 13] INFO - L3: translateBarCode: min [9.0] max [129.0] average [37.94] 
[thread 5] INFO - L3: createOrder: min [269.0] max [1269.0] average [479.95]   
[thread 5] INFO - L3: translateBarCode: min [9.0] max [124.0] average [30.34]  
[thread 3] INFO - L3: createOrder: min [236.0] max [1238.0] average [492.35]   
[thread 3] INFO - L3: translateBarCode: min [10.0] max [108.0] average [32.04] 
[thread 16] INFO - L3: changeOrder: min [662.0] max [4204.0] average [1379.84] 
[thread 17] INFO - L3: createOrder: min [236.0] max [1335.0] average [521.18]  
[thread 16] INFO - L3: translateBarCode: min [10.0] max [112.0] average [34.87]
[thread 17] INFO - L3: translateBarCode: min [10.0] max [103.0] average [36.45]
[thread 13] INFO - L3: changeOrder: min [617.0] max [4094.0] average [1520.84] 
[thread 13] INFO - L3: translateBarCode: min [9.0] max [108.0] average [31.38] 
[thread 11] INFO - L3: changeOrder: min [620.0] max [4099.0] average [1316.38] 
[thread 5] INFO - L3: changeOrder: min [647.0] max [4154.0] average [1384.15]  
[thread 5] INFO - L3: translateBarCode: min [8.0] max [110.0] average [31.42]  
...
...

基本的なsubstrとCollections.sortタイプのものを使用して、このようなCVS形式に正常に取り込むことができます。

API, Min, Max, Average
capturePayment, 232.0, 1800.0, 687.68
capturePayment, 268.0, 1853.0, 761.44
capturePayment, 301.0, 2612.0, 753.69
capturePayment, 309.0, 2632.0, 766.31
...
...

私の問題は、重複するすべてのAPI時間を平均してAPIごとに1つのエントリにすることです(つまり、各APIの平均最小/最大/平均)。元のファイルに重複があり、並べ替えられていないため、続行する方法がわかりません。

私の最大の問題は、APIの数が常に同じであるとは限らないことです。つまり、capturePayment呼び出しが10回あるのに、createOrdersが20回ある可能性があります。そうでなければ、私は大まかに機能するモデルを持っています。誰かが私にいくつかのポインタを教えてもらえますか?

[編集]

以下の「registerAPI」ソリューションで、もうすぐです。計算される平均は、Excelでの平均とは少し異なります。これが私のコードです。私の唯一の考えは、おそらくStringsからDoublesにキャストすると、精度が台無しになりますか?

    while ((line = br.readLine()) != null) {
        if (line.contains("L3")) {
            int x,y;
            x = line.indexOf("L3: ") + "L3: ".length();
            y = line.indexOf(":", x);
            String name = line.substring(x,y).trim();
            x = line.indexOf("min [") + "min [".length();
            y = line.indexOf("]", x);
            String min = line.substring(x,y).trim();
            x = line.indexOf("max [") + "max [".length();
            y = line.indexOf("]", x);
            String max = line.substring(x,y).trim();
            x = line.indexOf("average [") + "average [".length();
            y = line.indexOf("]", x);
            String average = line.substring(x,y).trim();
            pStreamArray.add(name + ", " + min + ", " + max + ", " + average);
            double[] apiValues = new double[3];
            apiValues[0] = Double.valueOf(min);
            apiValues[1] = Double.valueOf(max);
            apiValues[2] = Double.valueOf(average);
            parseAPILogs.registerAPI(name, apiValues);
        }
    }

    Iterator iterator = averagePerAPI.keySet().iterator();
    while (iterator.hasNext()) {
        String key = iterator.next().toString();
        double[] values = averagePerAPI.get(key);
        String valueString = "";
        for (int i = 0; i < values.length; i++) {
            valueString += values[i] + ", ";
        }
        System.out.println(key + " " + valueString); 
        pStreamCombined.println(key + " " + valueString);
    }

[編集]

上記のコードに数学的欠陥があることがわかりました。3つの数値の平均は最初の2つの数値の平均と等しくなく、3番目の数値の平均とは等しくありません。

例:(395 + 415 + 412)/ 3 = 407.33

(395 + 415)/ 2 = 405(405 + 412)/ 2 = 408.5

4

1 に答える 1

1

Map私が見ているように、これは平均的なコンテナで実現できます。

MINコンテナは、現在の合計と現在のカウントを持つクラスMAXですAVERAGE

public class APIData {

    private double min;
    private double max;
    private double average;
    private int amount;

    public void addValues(double[] values) {
        min += values[0];
        max += values[1];
        average += values[2];
        amount++;
    }

    public double getAPIMin() {
        return min / amount;
    }

    public double getAPIMax() {
        return max / amount;
    }

    public double getAPIAverage() {
        return average / amount;
    }

}

地図上で:

Map<String,APIData> averagePerAPI = new LinkedHashMap<String,int[]>();

このマップのキーはAPIの名前であり、値はサイズ3の配列であり、上記のコードのロジックにより、特定の順序でdouble保存します。{MIN, MAX, AVERAGE}

最後に、マップが提供するさまざまな方法を利用して、マップを管理するだけです。たとえば、registerAPIAPIのデータを保存するメソッドが既存のデータを更新するとします。

public void registerAPI(String apiName, double[] apiValues) {
    if(!averagePerAPI.containsKey(apiName)) {
        APIData data = new APIData();
        data.addValues(apiValues)
        averagePerAPI.put(apiName, data);
    } else {
        averagePerAPI.get(apiName).addValues(apiValues);
    }
}

APIの特定の値を知りたい場合はgetAPIMin()getAPIMax()またはgetAPIAverage()メソッドを呼び出すだけです。

于 2012-10-03T20:55:44.397 に答える