如何将剩余n个元素批量添加至ArrayList?区块链程序中剩余交易区块的实现方案
解决区块链程序剩余交易未生成区块及批量添加元素问题
看起来你遇到了两个核心问题:一是不足10笔的剩余交易无法生成对应区块,二是想了解如何批量向ArrayList添加元素。我来一步步帮你解决:
1. 修复剩余交易未生成区块的问题
你的当前代码只在交易数累计到10笔时生成区块,但循环结束后,剩下的不足10笔交易(比如你案例中的第21-23笔)没有被处理。另外还有个隐藏bug:你一直在复用同一个Transaction对象,清空列表会导致已生成区块的交易数据被意外清空(因为Java是引用传递)。
修改后的homework()方法如下:
static void homework() throws IOException { int count = 0; Transaction tranxLst = new Transaction(); Block genesis = new Block("0"); System.out.println(genesis); // 维护上一个区块的哈希,保证区块链的链式结构(原代码所有区块prevHash都是0,不符合区块链逻辑) String prevBlockHash = genesis.getHeader().getCurrHash(); int blockIndex = 1; // 创世区块索引为0,后续区块从1开始递增 BufferedReader bf = new BufferedReader(new FileReader("dummytranx.txt")); String line = bf.readLine(); while (line != null) { tranxLst.add(line); line = bf.readLine(); count++; if (count % 10 == 0) { Block newBlock = new Block(prevBlockHash); newBlock.getHeader().setIndex(blockIndex); newBlock.setTranx(tranxLst); System.out.println(newBlock); // 更新上一个区块哈希和索引 prevBlockHash = newBlock.getHeader().getCurrHash(); blockIndex++; // 新建Transaction对象,避免复用导致的数据覆盖问题 tranxLst = new Transaction(); } } // 循环结束后,处理剩余的不足10笔的交易 if (!tranxLst.getTranxLst().isEmpty()) { Block lastBlock = new Block(prevBlockHash); lastBlock.getHeader().setIndex(blockIndex); lastBlock.setTranx(tranxLst); System.out.println(lastBlock); } bf.close(); }
关键修改说明:
- 新增循环结束后的判断:检查
tranxLst是否还有未处理的交易,有则生成最后一个区块 - 替换
clear()为新建Transaction对象:每个区块持有独立的交易列表,避免引用共享导致的数据丢失 - 修复区块链链式结构:维护
prevBlockHash和blockIndex,让每个区块的prevHash指向前一个区块的currHash,同时正确递增区块索引
2. 批量添加元素到ArrayList的方法
如果需要批量将多个元素添加到ArrayList,推荐使用List.addAll()方法,它比逐个调用add()更高效,尤其是处理大量数据时。
举个例子,如果你先把剩余交易收集到一个临时列表,再批量添加:
// 临时存储一批交易 List<String> batchTranxs = new ArrayList<>(); // 假设这里收集了剩余的3笔交易 batchTranxs.add("alice|bob|credit|21.0"); batchTranxs.add("alice|bob|credit|22.0"); batchTranxs.add("alice|bob|debit|23.0"); // 批量添加到Transaction的列表中 tranxLst.getTranxLst().addAll(batchTranxs);
你也可以把读取逻辑改成批量收集后再添加,比如每10笔作为一个批量,一次性加入tranxLst,这样能减少方法调用次数,提升效率。
额外优化建议
- 你的
Block构造方法中,计算哈希时调用了getBytes(),但此时tranx还未被设置,这会导致同一个prevHash的区块哈希一致(因为序列化时tranx为null)。建议在设置tranx后重新计算并设置currHash,或者调整哈希计算时机。 - 可以给
Transaction类添加一个批量添加的方法,比如:
public void addAll(List<String> tranxs) { tranxLst.addAll(tranxs); }
这样调用起来更简洁。
内容的提问来源于stack exchange,提问作者Jenkins2000
相关产品推荐
相关产品推荐

