ここに1つの提案があります:
public Map<Long,List<Item>> group_items(List<Item> items,long sample_period) {
Map<Long,List<Item>> grouped_result = new HashMap<Long,List<Item>>();
long group_key;
for (Item item: items) {
group_key = item.timestamp / sample_period;
if (grouped_result.containsKey(group_key)) {
grouped_result.get(group_key).add(item);
}
else {
grouped_result.put(group_key, new ArrayList<Item>());
grouped_result.get(group_key).add(item);
}
}
return grouped_result;
}
sample_period は、グループ化する秒数です: 3600 = 時間、900 = 15 分
もちろん、マップ内のキーは非常に大きな数になる可能性があります (サンプル期間によって異なります) が、このグループ化はグループの内部時間順序を保持します。つまり、下位のキーは時間順序で最初に来るキーです。元のリストのデータが時間順に並べられていると仮定すると、もちろん最初のキーの値を取得し、それをキーから差し引くことができます。このようにして、キー 0、1 などを取得します。その場合、for ループを開始する前に次のものが必要です。
int 減算 = items.get(0).timestamp / sample_period; // 両方の数値が ints/longs であるため、整数除算があることに注意してください
次に、for ループ内で次のようにします。
group_key = items.timestamp / sample_period - 減算;
これらの行に沿った何かが機能します。つまり、説明したようにデータセットをグループ化します。次に、結果のリストに min max avg などを適用できます。しかし、これらの関数はもちろん個々のグループ リストを繰り返し処理する必要があるため、これらの計算をこのソリューションに組み込み、Aggregates が avg、min、max、次に、グループ内のアイテムのリスト? 性能に関しては許容範囲だと思います。これは単純な O(N) ソリューションです。編集:
最小値、最大値、平均値も計算する、より完全なソリューション/提案を追加したいだけです。
public class Aggregate {
public double avg;
public double min;
public double max;
public List<Item> items = new ArrayList<Item>();
public Aggregate(Item item) {
min = item.value;
max = item.value;
avg = item.value;
items.add(item);
}
public void addItem(Item item) {
items.add(item);
if (item.value < this.min) {
this.min = item.value;
}
else if (item.value > this.max) {
this.max = item.value;
}
this.avg = (this.avg * (this.items.size() - 1) + item.value) / this.items.size();
}
}
public Map<Long,Aggregate> group_items(List<Item> items,long sample_period) {
Map<Long,Aggregate> grouped_result = new HashMap<Long,Aggregate>();
long group_key;
long subtract = items.get(0).timestamp / sample_period;
for (Item item: items) {
group_key = items.timestamp / sample_period - subtract;
if (grouped_result.containsKey(group_key)) {
grouped_result.get(group_key).addItem(item);
}
else {
grouped_result.put(group_key, new Aggregate(item));
}
}
return grouped_result;
}
それは大まかな解決策です。集計などにさらにいくつかのプロパティを追加したい場合があります。