2017-03-17 1 views
-1

supposer flux de TXN, où chaque TXN a des champs suivantsComment utiliser le regroupement, les agrégats, la transformation et le filtrage sur flux

{date, amt, nom, marchand}
donné de flux TXN
groupe par AAAA mm // pli 1
dans le groupe (aaaa-mm); Carte de nouvel objet dépenses (revenus, dépenses)
si le montant> 0 alors le revenu + = amt // pli conditionnel 2.a
si le montant < 0 + a ensuite passé = amt // pli conditionnel 2.b

me demande Quelles sont les approches à réaliser ci-dessus en Java. Essayé ci-dessous, il est très loin

txns 
       .stream() 
       .collect(
        Collectors.groupingBy(
         Txn::getYearMonth, 
         Collectors.mapping(
          getExpense, 
          Collectors.toList()))); 

getexpense est la carte de fonction je l'ai écrit pour transformer Txn pour objet des dépenses.

Répondre

0

Je pense que vous êtes bloqué sur l'étape globale. Le code affiché entraînera ceci:

Map<YearMonth, List<Expense>> 

Alors que je devine que vous voulez:

Map<YearMonth, Expense> // transactions aggregated into a single Expense 

Pour ce faire, vous devez créer un collecteur qui peut agréger Expense objets.

Il ressemblerait à ceci:

Collector.of(
    Expense::new, 
    (Expense e, Transaction t) -> e.add(t), 
    (e1, e2) -> new Expense(e1, e2) 
); 

Votre classe de dépenses devra:

  1. un constructeur public vide
  2. un constructeur qui prend 2 dépenses et crée une nouvelle dépense agrégée
  3. une méthode add qui ajoute un Transaction à un Expense

Quelque chose comme ceci:

public class Expense { 
    private double income; 
    private double spent; 

    public Expense() { 
    } 

    public Expense(Expense e1, Expense e2) { 
    this.income = e1.income + e2.income; 
    this.spent = e1.spent + e2.spent; 
    } 

    public void add(Transaction t) { 
    this.income += t.getAmount() > 0 ? t.getAmount() : 0; 
    this.spent += t.getAmount() < 0 ? t.getAmount() : 0; 
    } 
} 

Vous pouvez ensuite utiliser ce Collector dans le groupingBy:

groupingBy(Txn::getYearMonth, myCollector) 

Et le résultat seront regroupées les dépenses en un seul objet Expense.

Mise à jour

donc comme ceci:

Collector<Transaction, Expense, Expense> c = Collector.of(
    Expense::new, 
    (Expense e, Transaction t) -> e.add(t), 
    (e1, e2) -> new Expense(e1, e2) 
); 

Map<YearMonth, Expense> collect = txns.stream() 
    .collect(Collectors.groupingBy(Transaction::getYearMonth, c)); 
+0

culd u me aider à définir myCollector – bajju

+0

je suppose, le montant de la transaction devrait être ajoutée à '' income' ou spent' plutôt que d'écraser il ... – Holger

+0

Ouais, semble que j'ai raté cela, la mise à jour – john16384