2017-11-28 15 views
3

Java 8 + JavaFXを使用時間の経過とともにJava 8の複合グループ化

私はいくつかのデータ分析を行い、結果をXYチャートに出力しようとしています。 私自身が離れ平方私のチャートを得ている、とのように、それは構造を受け付けますので、

public class funds{ 
    private long id; 
    private String userName; 
    private BigDecimal current; 
    private Timestamp createdAt; 

    ....constructors/getters/setters.... 
} 

fundsオブジェクトはすべてのために作成されるように私のデータは、カスタムオブジェクトに格納されて

ObservableList<Data<Timestamp, BigDecimal>> 

1分間隔で定期的にTaskに送信します。

私は時間平均の合計をfunds.currentと表記したいと思います。 だから、私は通常、すべてのユーザーに対して1分ごとに合計し、1時間ごとに平均します。

SELECT FLOOR(UNIX_TIMESTAMP(created_at)/(60*60)) AS hour, AVG(current) 
FROM (
    SELECT FLOOR(UNIX_TIMESTAMP(created_at)/60) AS minute, SUM(current) as current, created_at 
    FROM funds 
    GROUP BY minute 
) as table1 
GROUP BY hour; 

をしかし、この例では、私が直接SQLアクセスを持っていない、とJavaを使用する必要があります。MySQLでは、私はこれを行うことができます。私はストリームとCollectors.groupingByを見てみましたが、私は私の欲しいものを得るために十分に私の頭を包み込むことはできません。

またCollectorsダブルスは、財務データのために完全にひどいと、私は必要のBigDecimal、で使用するためのあらゆる機能を持っていないように見えます。

誰でも正しい方向に向けることができますか?あなたが本当にダブルスを使用したくない場合は

+3

を私はこれを学ぶための方法を提案しているいくつかの簡単なテストケースを作るために、様々な 'groupingBy()'コレクターにして実験します彼らが何をし、どのようにそれらを使用することができます参照してください。インナーセレクトのテーブル(「資金」)を表す小さなデータストリームから始め、インナーセレクトだけを実行しようとします。その結果を外側のselectのための別の 'groupingBy()'に渡します。 –

答えて

3

、これを試してみてください。

Map<Long, BigDecimal> hourAverages = funds.stream() 
    //group by minute; as a result we have Map<Long, BigDecimal> 
    .collect(toMap(f -> f.createdAt.getTime()/6000, f -> f.current, BigDecimal::add)) 
    .entrySet().stream() 
    //group by hours; here we use BigDecimal[] to store sum and count; 
    //as a result we have Map<Long, BigDecimal[]> 
    .collect(groupingBy(e -> e.getKey()/60, 
      collectingAndThen(
        reducing(new BigDecimal[] {BigDecimal.ZERO, BigDecimal.ZERO}, 
         e -> new BigDecimal[]{e.getValue(), BigDecimal.ONE}, 
         (a, b) -> new BigDecimal[]{a[0].add(b[0]), a[1].add(b[1])}), 
        //finally divide by count 
        a -> a[0].divide(a[1], BigDecimal.ROUND_UP)))); 
+2

うわー、いいね。私は疑問に思っています:第2の 'reduce'のアイデンティティ値は、' new BD [] {BD.ZERO、BD.ONE} 'の代わりに' new BD [] {BD.ZERO、BD.ZERO} ?さもなければ、1要素のリストはカウント2で終わるのですか? –

+0

なぜdownvote?たぶん何かが間違っているか、何かを改善することができますか? –

関連する問題