You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何退出死循环并生成含100个唯一值的Vector

解决Vector填充唯一值时的无限循环问题

嘿,我来帮你拆解下这个问题,以及给出可行的解决方案:

为什么会陷入无限循环?

你当前的代码用了Math.abs(r.nextGaussian())生成绝对值的高斯分布随机数,然后通过Math.round(val*10)/10.0把它保留成一位小数。但高斯分布(正态分布)的取值**绝大多数集中在03之间**(因为标准差是1,绝对值后99.7%的值在03范围内)。

一位小数的话,这个范围内的唯一值总共也就31个(0.0、0.1、0.2……3.0),更大的值出现的概率极低极低,根本凑不够100个唯一值。循环条件i<100永远满足,自然就无限跑下去了。

另外还要提一句:你后面填充v2的set(j, ...)会抛出ArrayIndexOutOfBoundsException——因为Vector(100)只是设置了初始容量,实际元素数量是0,set方法需要索引对应的位置已经有元素才行,应该用add方法。

解决方案:两种思路解决问题

思路1:扩大唯一值的候选池

要凑够100个唯一值,你需要让生成的随机数有足够多的可能取值。比如:

  • 保留更多小数位(比如两位),这样候选值的数量会大幅增加;
  • 改用均匀分布的随机数(比如r.nextDouble()),取值范围更均匀,更容易生成唯一值。

这里给你修改后的代码,同时用上泛型(避免类型转换问题)和更高效的HashSet来判断重复:

public static void main(String[] args) { 
    Vector<Double> v1 = new Vector<>(100);
    Vector<Double> v2 = new Vector<>(100);
    // 用HashSet记录已存在的值,contains判断效率远高于Vector
    HashSet<Double> seenValues = new HashSet<>();
    Random r = new Random(); 
    int i = 0; 

    while(i < 100){ 
        double val = Math.abs(r.nextGaussian()); 
        // 保留两位小数,大幅增加可能的唯一值数量
        double h = Math.round(val * 100) / 100.0; 
        // HashSet的add方法返回true表示该值不存在,添加成功
        if (seenValues.add(h)){ 
            v1.add(h); 
            i++; 
        } 
    } 

    // 正确填充v2的方式:用add而不是set
    for(int j=0; j<v1.size(); j++) {
        v2.add(v1.get(j));
    }
}

思路2:给循环加退出条件(避免死循环)

如果你坚持要用一位小数的高斯值(虽然凑不够100个),可以给循环加一个最大尝试次数,这样即使凑不够100个,也不会无限卡着,同时能填充最多的唯一值:

public static void main(String[] args) { 
    Vector<Double> v1 = new Vector<>(100);
    Vector<Double> v2 = new Vector<>(100);
    HashSet<Double> seenValues = new HashSet<>();
    Random r = new Random(); 
    int i = 0; 
    // 设置最大尝试次数,比如10000次,避免无限循环
    int maxAttempts = 10000;
    int attempts = 0;

    while(i < 100 && attempts < maxAttempts){ 
        double val = Math.abs(r.nextGaussian()); 
        double h = Math.round(val * 10) / 10.0; 
        if (seenValues.add(h)){ 
            v1.add(h); 
            i++; 
        } 
        attempts++;
    } 

    // 填充v2
    for(int j=0; j<v1.size(); j++) {
        v2.add(v1.get(j));
    }

    // 可以打印实际填充的数量,方便调试
    System.out.println("实际填充的唯一值数量:" + v1.size());
}

额外优化建议

  • 尽量用泛型(比如Vector<Double>),避免运行时的类型转换问题;
  • 用HashSet代替Vector的contains方法:Vector的contains是线性遍历,元素越多越慢,HashSet的判断是O(1)时间复杂度,效率高很多;
  • 如果不需要Vector的线程安全特性,建议用ArrayList代替Vector,性能更好。

内容的提问来源于stack exchange,提问作者Shereen Saleh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:04:12