如何拆分科学计数法字符串的尾数与指数并修复Map存储结果异常问题
解决科学计数法字符串拆分与对象生成问题
问题分析
你的代码出现错误输出的核心原因有两个:
- 共享列表对象导致的错误:你定义的
List<Integer> exs = new LinkedList<>();是一个全局实例,每次向separateExponent中put的时候,所有键都指向同一个列表对象。因此每次添加指数时,都会往这个唯一的列表里加元素,最终所有键的列表内容完全相同。 - 低效且易出错的字符遍历拆分:通过逐个字符判断来拆分尾数和指数的逻辑,不仅繁琐,还无法处理多位数的尾数/指数(比如
12e5或2e10这种场景),扩展性极差。
修复现有代码的方案
针对上述问题,我们可以对代码做以下关键修改:
- 移除全局的
exs列表,每次需要为新尾数创建列表时再初始化 - 使用
split("e")方法直接拆分每个科学计数法字符串,逻辑更简洁可靠
修复后的代码如下:
public List<ScientificNumber> getScientificNumbers() { List<ScientificNumber> result = new LinkedList<>(); Map<Integer, List<Integer>> separateExponent = new LinkedHashMap<>(); for(String str : scientificNumberData){ // 直接用split拆分尾数和指数部分 String[] parts = str.split("e"); int mantissa = Integer.parseInt(parts[0]); int exponent = Integer.parseInt(parts[1]); // 处理Map的逻辑:如果尾数已存在,就往对应的列表加指数;否则创建新列表 separateExponent.computeIfAbsent(mantissa, k -> new LinkedList<>()).add(exponent); } // 从Map转换为目标List for(Map.Entry<Integer, List<Integer>> entry : separateExponent.entrySet()){ int mantissa = entry.getKey(); for(int exponent : entry.getValue()){ result.add(new ScientificNumber(mantissa, exponent)); } } return result; }
这里用到了Map.computeIfAbsent()方法,它会自动判断键是否存在:如果不存在,就执行Lambda表达式创建新列表并put进去;如果存在,就直接返回已有的列表,逻辑简洁且不易出错。
更简洁的最优方案
如果你不需要中间的Map(只是想直接生成List<ScientificNumber>),可以直接遍历字符串并转换,甚至用Stream API一行搞定:
public List<ScientificNumber> getScientificNumbers() { return Arrays.stream(scientificNumberData) .map(str -> { String[] parts = str.split("e"); int mantissa = Integer.parseInt(parts[0]); int exponent = Integer.parseInt(parts[1]); return new ScientificNumber(mantissa, exponent); }) .collect(Collectors.toList()); }
这个方案跳过了中间的Map步骤,直接将每个字符串转换为ScientificNumber对象,代码更简洁高效,完全满足生成目标List的需求。
如果确实需要先通过Map合并相同尾数的指数(比如后续要做去重等操作),可以在Stream中先分组:
public List<ScientificNumber> getScientificNumbers() { return Arrays.stream(scientificNumberData) .map(str -> str.split("e")) .collect(Collectors.groupingBy( parts -> Integer.parseInt(parts[0]), Collectors.mapping( parts -> Integer.parseInt(parts[1]), Collectors.toList() ) )) .entrySet() .stream() .flatMap(entry -> entry.getValue().stream() .map(exponent -> new ScientificNumber(entry.getKey(), exponent))) .collect(Collectors.toList()); }
这个分组的方式和你之前的Map逻辑一致,但用Stream API实现更优雅。
内容的提问来源于stack exchange,提问作者TheFoxterGirl
相关产品推荐
相关产品推荐

