Java如何高效将数组中带数量属性的对象拆分为多个单对象
问题描述
我是Java初学者,若问题表述存在疏漏还请谅解。
需求为:编写Java函数处理存储成组水果的数组,将数组中携带quantity属性的成组水果对象,按照数量值拆分为对应个数、quantity值为1的单个对象存入结果数组,要求实现逻辑尽可能高效。
输入输出示例
- 示例1输入:
[{"name": "grapes", "quantity": 2}]
- 示例1输出:
[{"name": "grapes", "quantity": 1}, {"name": "grapes", "quantity": 1}]
- 示例2输入:
[ {"name": "currants", "quantity": 1}, {"name": "grapes", "quantity": 2}, {"name": "bananas", "quantity": 2} ]
- 示例2输出:
[ {"name": "currants", "quantity": 1}, {"name": "grapes", "quantity": 1}, {"name": "grapes", "quantity": 1}, {"name": "bananas", "quantity": 1}, {"name": "bananas", "quantity": 1} ]
实现方案
核心优化思路:
ArrayList默认初始容量为10,存满后会按1.5倍扩容,每次扩容需要做原数组的全量拷贝,是可规避的性能损耗。实现时先遍历一次原数组累加所有quantity值得到结果集总长度,直接用该长度初始化结果集合,避免扩容开销;之后遍历每个成组水果,循环生成对应数量的单份水果对象即可。整体逻辑无冗余遍历、无中间对象额外开销,时间复杂度为O(N)(N为拆分后总元素数),为最优实现。
1. 定义水果实体类
如果使用JDK16及以上版本,可直接用record简化实体编写:
public record Fruit(String name, int quantity) {}
如果是JDK8及以下版本,用普通实体类即可:
public class Fruit { private String name; private int quantity; public Fruit(String name, int quantity) { this.name = name; this.quantity = quantity; } public String getName() { return name; } public int getQuantity() { return quantity; } }
2. 拆分逻辑实现
对应JDK16+record写法的实现代码:
import java.util.ArrayList; import java.util.List; public class FruitSplitUtil { public static List<Fruit> splitGroupedFruits(List<Fruit> sourceList) { // 提前计算结果集总容量,避免ArrayList扩容开销 int totalCount = 0; for (Fruit fruit : sourceList) { totalCount += fruit.quantity(); } List<Fruit> result = new ArrayList<>(totalCount); // 遍历拆分每个成组水果 for (Fruit fruit : sourceList) { String fruitName = fruit.name(); int quantity = fruit.quantity(); for (int i = 0; i < quantity; i++) { result.add(new Fruit(fruitName, 1)); } } return result; } // 测试验证 public static void main(String[] args) { List<Fruit> testInput = List.of( new Fruit("currants", 1), new Fruit("grapes", 2), new Fruit("bananas", 2) ); List<Fruit> result = splitGroupedFruits(testInput); result.forEach(f -> System.out.printf("{name: \"%s\", quantity: %d}%n", f.name(), f.quantity())); } }
如果使用JDK8低版本实体类,只需要把代码里调用fruit.quantity()、fruit.name()的位置替换为fruit.getQuantity()、fruit.getName()即可,逻辑完全一致。
运行测试代码的输出和预期结果完全匹配,可直接使用。
内容的提问来源于stack exchange,提问作者David Prieto
相关产品推荐
相关产品推荐

