Java中StringTokenizer.countTokens()循环使用异常问题解析
StringTokenizer循环赋值数组仅部分生效的原因及解决思路
问题根源
原代码的核心问题在于每次调用st.countTokens()都会实时计算剩余未被读取的token数量,而循环中每次执行st.nextToken()都会消耗一个token,导致countTokens()的返回值在循环过程中不断递减。
以你输入的9个值为例:
- 初始时
st.countTokens()返回9,数组长度设为9 - 第一次循环:
i=0,判断0<9成立,读取1个token,剩余8个 - 第二次循环:
i=1,判断1<8成立,读取1个token,剩余7个 - ...
- 第五次循环:
i=4,判断4<5成立,读取1个token,剩余4个 - 第六次循环:
i=5,此时st.countTokens()返回4,5<4不成立,循环直接终止
最终只完成了前5个元素的赋值,数组未被赋值的位置默认填充0.0。
修复方案的原理
你提前将st.countTokens()的结果存入numTokens变量,相当于缓存了初始的总token数量。这个值不会随着token的消耗而变化,循环会严格执行numTokens次(也就是9次),确保所有token都被读取并赋值给数组。
避免此类问题的方法
- 缓存
countTokens()结果:和你采用的方法一致,提前获取总token数并复用,不要在循环条件中重复调用countTokens() - 改用
while循环遍历:依赖hasMoreTokens()判断是否还有剩余token,无需依赖token数量:
StringTokenizer st = new StringTokenizer(values,","); prices = new double[st.countTokens()]; int i = 0; while(st.hasMoreTokens()) { token = st.nextToken(); prices[i++] = Double.parseDouble(token); }
- 使用更现代的字符串分割方式:StringTokenizer是较老旧的API,推荐用
String.split()或Stream API简化代码,可读性和稳定性更高:
// 方式1:split + 循环 String[] tokens = values.split(","); prices = new double[tokens.length]; for(int i=0; i<tokens.length; i++) { prices[i] = Double.parseDouble(tokens[i]); } // 方式2:Stream API(Java 8+) prices = Arrays.stream(values.split(",")) .mapToDouble(Double::parseDouble) .toArray();
内容的提问来源于stack exchange,提问作者KittenLover84
相关产品推荐
相关产品推荐

