如何创建具备ArrayList动态特性的int[]以实现粒子尺寸分布统计?
解决粒子尺寸分布统计的动态数组问题
嘿,这个场景我太熟悉了——显微镜图像的粒子尺寸波动确实大,固定长度数组完全顶不住,给你几个实用的解决方案:
方案1:先找最大尺寸再初始化数组(最直观)
先遍历一次粒子Map,找到最大的粒子尺寸,然后用这个尺寸来确定数组的长度。这样既不会有索引越界问题,也不会浪费太多空间:
private int[] particleSizeDistribution(Map<Integer, List<Pixel>> particleMap) { // 第一步:遍历找到最大粒子尺寸 int maxParticleSize = 0; for (List<Pixel> pixelList : particleMap.values()) { int currentSize = pixelList.size(); if (currentSize > maxParticleSize) { maxParticleSize = currentSize; } } // 初始化数组,长度设为max+1(因为索引从0开始,要覆盖到max尺寸的位置) int[] distribution = new int[maxParticleSize + 1]; // 第二步:统计每个尺寸的粒子数量 for (List<Pixel> pixelList : particleMap.values()) { int size = pixelList.size(); distribution[size]++; } return distribution; }
这个方案的优点是操作简单,后续用数组访问也高效,唯一的小代价是多遍历一次Map,但对于粒子数据量来说,这点开销几乎可以忽略。
方案2:用Map动态统计(最灵活)
如果不想提前遍历找最大值,直接用Map<Integer, Integer>来统计每个尺寸出现的次数,完全动态适配所有尺寸:
private Map<Integer, Integer> particleSizeDistribution(Map<Integer, List<Pixel>> particleMap) { Map<Integer, Integer> sizeCountMap = new HashMap<>(); for (List<Pixel> pixelList : particleMap.values()) { int size = pixelList.size(); // 用getOrDefault简化计数逻辑,不存在的尺寸默认计数0 sizeCountMap.put(size, sizeCountMap.getOrDefault(size, 0) + 1); } return sizeCountMap; }
这个方案的好处是不需要关心尺寸范围,只统计实际出现过的尺寸,后续如果需要转成数组,再遍历Map找最大值就行;如果只是需要查询某个尺寸的粒子数量,直接用sizeCountMap.get(size)就很方便。
方案3:用ArrayList动态扩容(如果你坚持用列表)
如果你一定要用ArrayList,那每次遇到新的尺寸时,先检查列表长度是否足够,不够就扩容并填充0,再进行计数:
private List<Integer> particleSizeDistribution(Map<Integer, List<Pixel>> particleMap) { List<Integer> distributionList = new ArrayList<>(); for (List<Pixel> pixelList : particleMap.values()) { int size = pixelList.size(); // 扩容列表到size+1的长度,中间空缺的位置填0 while (distributionList.size() <= size) { distributionList.add(0); } // 对应索引位置计数+1 distributionList.set(size, distributionList.get(size) + 1); } return distributionList; }
这种方式完全动态,但如果尺寸跨度很大,列表里会有很多0,而且扩容时会有一点额外开销,适合对列表有强需求的场景。
总结推荐
- 如果后续要做直方图这类需要连续索引的操作,优先选方案1;
- 如果只需要统计存在的尺寸,或者尺寸跨度极大,选方案2更高效;
- 方案3可以作为备选,但一般前两种更实用。
内容的提问来源于stack exchange,提问作者erbld
相关产品推荐
相关产品推荐

