首页 > 解决方案 > 根据值和大小的总和在多个列表中拆分对象列表

问题描述

我有一个问题,我不知道如何根据条件和大小拆分列表。

现在,我可以根据大小拆分列表,但如何添加条件,例如值的总和。

如果 amt 的总和 > 100 则拆分到下一个新列表。如果 amt < 100 和 size 的总和必须 <= 3。

示例输入:

[[Txn{txnId='T1', amt=81}], [Txn{txnId='T2', amt=5}], [Txn{txnId='T3', amt=12}], [Txn{txnId='T4', amt=28}], [Txn{txnId='T5', amt=78}], [Txn{txnId='T6', amt=8}], [Txn{txnId='T7', amt=7}], [Txn{txnId='T8', amt=65}]]

预期输出:

[
  [Txn{txnId='T1', amt=81}, Txn{txnId='T2', amt=5}],
  [Txn{txnId='T3', amt=12}, Txn{txnId='T4', amt=28}],
  [Txn{txnId='T5', amt=78}, Txn{txnId='T6', amt=8}, Txn{txnId='T7', amt=7}], 
  [Txn{txnId='T8', amt=65}]
]

我的错误输出:

[
  [Txn{txnId='T1', amt=81}, Txn{txnId='T2', amt=5}, Txn{txnId='T3', amt=12}],
  [Txn{txnId='T4', amt=28}, Txn{txnId='T5', amt=78}, Txn{txnId='T6', amt=8}], 
  [Txn{txnId='T7', amt=7}, Txn{txnId='T8', amt=65}]
]

我的代码:

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

public class TestStream {
    public class Transaction {
        String txnId;
        int amount;

        public Transaction(String txnId, int amount) {
            this.txnId = txnId;
            this.amount = amount;
        }

        @Override
        public String toString() {
            return "Txn{" +
                    "txnId='" + txnId + '\'' +
                    ", amt=" + amount +
                    '}';
        }
    }

    public static <T> Collection<List<T>> partitionBasedOnSize(List<T> inputList) {
        final AtomicInteger counter = new AtomicInteger(0);
        return inputList.stream()
                .collect(Collectors.groupingBy(s -> counter.getAndIncrement()/3))
                .values();
    }

    @Test
    public void test() {
        List<Transaction> transactionList = new ArrayList<>();
        Transaction txn1 = new Transaction("T1", 81);
        Transaction txn2 = new Transaction("T2", 5);
        Transaction txn3 = new Transaction("T3", 12);
        Transaction txn4 = new Transaction("T4", 28);
        Transaction txn5 = new Transaction("T5", 78);
        Transaction txn6 = new Transaction("T6", 8);
        Transaction txn7 = new Transaction("T7", 7);
        Transaction txn8 = new Transaction("T8", 65);

        transactionList.add(txn1);
        transactionList.add(txn2);
        transactionList.add(txn3);
        transactionList.add(txn4);
        transactionList.add(txn5);
        transactionList.add(txn6);
        transactionList.add(txn7);
        transactionList.add(txn8);

        System.out.println(partitionBasedOnSize(transactionList).toString() + "\n");
    }
}

标签: javalistsplit

解决方案


如果有足够的时间,您可能会制定一个分类器函数来使用groupingBy()它来完成使用流的工作。

或者,您可以使用良好的老式命令式编程以良好的老式方式来完成,如下所示:

    public Collection<List<Transaction>> partition(List<Transaction> inputList)
    {
        List<List<Transaction>> partList = new LinkedList<>();
        List<Transaction> partition = new LinkedList<>();
        int partTotalAmt = 0;
        Iterator<Transaction> inputIter = inputList.iterator();
        while (inputIter.hasNext()) {
            Transaction tx = inputIter.next();
            partTotalAmt += tx.amount;
            partition.add(tx);
            if (!inputIter.hasNext() || 
                partTotalAmt > 100 || 
                partition.size() == 3) {
                partList.add(partition);
                partTotalAmt = 0;
                partition = new LinkedList<>();
            }
        }
        return partList;
    }

推荐阅读