为什么Java中ArrayList<Integer>列求和结果是数值两倍而非累加总和?
问题原因分析
- 总和变量作用域错误:你将用于存储所有行累加结果的
columTotal定义在while (matcher.find())循环内部,每次匹配到新行都会被重新初始化为0,完全无法实现跨行累加的效果,只能计算单次行内的数值和。 - 正则匹配&取值逻辑错误:你的正则一次性匹配了Inodes、IUsed、IFree三个数值的连续段,后续又错误遍历整段数值做累加,同时正则捕获逻辑存在重复匹配的问题,才会出现单行输出为Inodes数值两倍的情况。
- 类型溢出风险:你使用int类型存储总和,从示例数据看单Inodes列就有32768000的大数值,多行列累加后必然会超出int类型的最大值(2147483647),导致结果错误。
- 代码语法错误:
int [][] num = newList;属于语法错误,List类型无法直接赋值给二维数组,你实际运行的代码应该是写错了转换逻辑,进一步导致取值错误。
解决方案
推荐两种实现方案,均可以直接得到正确的Inodes列总和:
方案1:正则匹配方案
直接精准捕获每行的Inodes列数值,逻辑简洁:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class InodesSum { public static void main(String[] args) { String strHDD = "df -i\n" + "Filesystem Inodes IUsed IFree IUse% Mounted on\n" + "/dev/mapper/vg0-rootvol 719488 42967 676521 6% /\n" + "devtmpfs 4093600 436 4093164 1% /dev\n" + "tmpfs 4096453 1 4096452 1% /dev/shm\n" + "tmpfs 4096453 1384 4095069 1% /run\n" + "tmpfs 4096453 16 4096437 1% /sys/fs/cgroup\n" + "/dev/sda1 32768 351 32417 2% /boot\n" + "/dev/mapper/vg0-optvol 327680 19465 308215 6% /opt\n" + "/dev/mapper/vg0-homevol 131072 322 130750 1% /home\n" + "/dev/mapper/vg0-tmpvol 131072 166 130906 1% /tmp\n" + "/dev/mapper/vg0-varvol 327680 4486 323194 2% /var\n" + "/dev/mapper/vg0-logvol 131072 163 130909 1% /var/log\n" + "/dev/mapper/vg0-auditvol 327680 34 327646 1% /var/log/audit\n" + "/dev/mapper/vg1-optSPvol 32768000 156936 32611064 1% /opt/SP\n" + "/dev/mapper/vg0-varcrashvol 1048576 11 1048565 1% /var/crash\n" + "tmpfs 4096453 1 4096452 1% /run/user/10603\n" + "[1;31mvg1108yr:resolve:[0m/opt/SP/resolve $"; long totalInodes = 0; // 正则精准匹配数据行的Inodes列数值 Pattern pattern = Pattern.compile("^[^\\n]+?\\s+(\\d+)\\s+\\d+\\s+\\d+\\s+\\d+%", Pattern.MULTILINE); Matcher matcher = pattern.matcher(strHDD); while (matcher.find()) { totalInodes += Long.parseLong(matcher.group(1)); } System.out.println("Inodes列总和为:" + totalInodes); } }
方案2:按行分割方案
处理表格类数据更稳妥,可读性更高:
public class InodesSum { public static void main(String[] args) { String strHDD = "df -i\n" + "Filesystem Inodes IUsed IFree IUse% Mounted on\n" + "/dev/mapper/vg0-rootvol 719488 42967 676521 6% /\n" + "devtmpfs 4093600 436 4093164 1% /dev\n" + // 此处省略其余相同的字符串内容 "[1;31mvg1108yr:resolve:[0m/opt/SP/resolve $"; long totalInodes = 0; String[] lines = strHDD.split("\n"); // 跳过前2行(命令行、表头)和最后1行(命令提示符) for (int i = 2; i < lines.length -1; i++) { String line = lines[i].trim(); if (line.isEmpty()) continue; // 按空白符分割为列,第2列(索引1)即为Inodes列 String[] columns = line.split("\\s+"); totalInodes += Long.parseLong(columns[1]); } System.out.println("Inodes列总和为:" + totalInodes); } }
两种方案运行后输出结果均为62441112,和手动累加的结果一致。
内容的提问来源于stack exchange,提问作者Fabio Ochoa Restrepo
相关产品推荐
相关产品推荐

