【问题标题】:Java. Group and sum exact values in collection of Java Objects爪哇。在 Java 对象集合中对精确值进行分组和求和
【发布时间】:2020-09-03 15:25:10
【问题描述】:

啊啊啊,终于发生了,我请求帮助:(

让我们开始吧: 我有一个传入交易的列表,例如:

List<FinancialTransaction> incomingTransactions = new ArrayList();
incomingTransactions.add(new FinancialTransaction(1, 1, 2, 1000000));
incomingTransactions.add(new FinancialTransaction(2, 1, 2, 2000000));
incomingTransactions.add(new FinancialTransaction(3, 2, 1, 1000000));
incomingTransactions.add(new FinancialTransaction(4, 2, 1, 4000000));
incomingTransactions.add(new FinancialTransaction(5, 2, 3, 1000000));

金融交易 POJO:

public class FinancialTransaction {

    private Integer id;

    private Integer srcId;

    private Integer dstId;

    private Long amount;

    public Integer getId() {
        return id;
    }

    //getters, setters, constructors, toString
}

然后incomingTransactions移动到下面列出的方法,该方法必须创建一个新的Map,键为srcId,dstId为FinancialTransaction,按此键分组,对分组对象的“数量”值求和,并放入Id = sdcId的新对象and dstId, srcId = this.srcId, dstId = this.dstId, and amount = 所有分组对象的总和:

public class TransactionMerger {


    public static Map<String, FinancialTransaction> mergeTransactions(List<FinancialTransaction> financialTransactions) {

        Map<String, FinancialTransaction> mergedTransactions = new HashMap<>();

        for (FinancialTransaction ft: financialTransactions) {

            String key = ft.getSrcId() + "" + ft.getDstId();

            if (mergedTransactions.get(key) != null) {
                mergedTransactions.put(key, ft);
            } else {
//          Don't know to write here :/
            }

        }

        financialTransactions.clear();

        return mergedTransactions;
    }

}

这个方法必须吸收incomingTransactions返回类似的东西:

Key: 12 Value: FinancialTransaction {12, 1, 2, 3000000} //summed first and second values in incoming list
Key: 21 Value: FinancialTransaction {21, 2, 1, 5000000} //summed third and fourth values in incoming list
Key: 23 Value: FinancialTransaction {23, 2, 3, 1000000} //returned fifth values

请帮助我没有想法,我已经知道如何用复合键分组,从几个值,但是总和和分组 - 没有想法请帮助!!!!!!

谢谢大家!!!

【问题讨论】:

  • 我希望您只有 9 个源/目标 ID,否则您的密钥将不明确(例如 12 + "" + 31 + "" + 23
  • 你知道Map.merge方法吗?
  • @AndyTurner 是的,谢谢你,我忽略了这个案例 :( 也许我会在数字前添加一些空值,以使 smth 像 scr - 000001+ dst - 000002 = key- 000001000002,是坏还是坏?
  • 或者只是在中间放一个冒号。
  • @AndyTurner 太棒了!谢谢)))

标签: java collections stream java-stream pojo


【解决方案1】:
public static Map<String, FinancialTransaction> mergeTransactions(List<FinancialTransaction> financialTransactions) {

        Map<String, FinancialTransaction> mergedTransactions = new HashMap<>();

        for (FinancialTransaction ft: financialTransactions) {

            String key = ft.getSrcId() + "" + ft.getDstId();

            if (mergedTransactions.containsKey(key)) {
                //get the existing FinancialTransaction for the key and updates it's amount only
                mergedTransactions.get(key).setAmount(mergedTransactions.get(key).getAmount() + ft.getAmount());
            } else {
                //create new FinancialTransaction object for the map
                FinancialTransaction financialTransaction = new FinancialTransaction();
                //do not set Id for the new object, as its not db generated, key will behave like id
                financialTransaction.setSrcId(ft.getSrcId());
                financialTransaction.setDstId(ft.getDstId());
                financialTransaction.setAmount(ft.getAmount());
                mergedTransactions.put(key, financialTransaction);
            }
        }

        financialTransactions.clear();
        return mergedTransactions;
    }

希望这会有所帮助。我添加了 cmets,如果您需要更清晰的信息,请告诉我。

【讨论】:

  • 感谢劳山,它完美运行!现在对我来说很简单明了!太好了!!!!
  • 我很高兴它对你有用,但我建议你阅读@Andy 对这个问题的评论。他指出了您当前实施中的设计问题,希望您自己会注意到这一点,并正在使用您正在编写的解决方案进行工作/分析。
【解决方案2】:

首先,您必须在 FinancialTransaction 或实用程序中创建合并功能。现在,我在上面的类中添加。

public static FinancialTransaction merge(FinancialTransaction first, FinancialTransaction second){
  first.setAmount(first.getAmount() + second.getAmount());
  return first;
}

现在,让我们使用map.merge进行分组

incomingTransactions.stream()
  .collect(Collectors.toMap(trxn -> trxn.getSrcId() + "" + trxn.getDstId(), Function.identity() , FinancialTransaction::merge));

在这里,将使用生成的密钥进行分组,当我们遇到重复的密钥(或类似的交易)时,它将应用合并功能,该功能基本上将求和并返回金融交易的更新参考。

注意:正如 cmets 中所指出的,请注意如何生成分组密钥。

【讨论】:

    猜你喜欢
    • 2011-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-08
    • 2023-02-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多