Java 随机颜色字符串

15

我编写了这个Java方法,但有时颜色字符串只有5个字符长。有人知道为什么吗?

@Test
public void getRandomColorTest() {
    for (int i = 0; i < 20; i++) {
        final String s = getRandomColor();
        System.out.println("-> " + s);
    }
}

 public String getRandomColor() {
    final Random random = new Random();
    final String[] letters = "0123456789ABCDEF".split("");
    String color = "#";
    for (int i = 0; i < 6; i++) {
        color += letters[Math.round(random.nextFloat() * 15)];
    }
    return color;
}

3
为什么不使用random.nextInt(16)而改用Math.round(random.nextFloat() * 15)呢? - Thomas
使用color += letters[random.nextInt(letters.length)];代替color += letters[Math.round(random.nextFloat() * 15)];。 - Manindar
3个回答

32

使用浮点数和使用round不是创建随机颜色的安全方法。

实际上,颜色代码是以十六进制格式表示的整数。您可以像这样轻松地创建这样的数字:

import java.util.Random;

public class R {
    
    public static void main(String[] args) {
        
        // create random object - reuse this as often as possible
        Random random = new Random();
        
        // create a big random number - maximum is ffffff (hex) = 16777215 (dez)
        int nextInt = random.nextInt(0xffffff + 1);
        
        // format it as hexadecimal string (with hashtag and leading zeros)
        String colorCode = String.format("#%06x", nextInt);
        
        // print it
        System.out.println(colorCode);
    }

}

演示


1
加一分,因为您花时间了解了OP 真正想要的,并提交了一个更好的方法。 - Bathsheba
这很容易就完成了复制/粘贴,并且效果很好。谢谢! - CANDIMAN

3
你的 split 会生成一个长度为17的数组,开头有一个空字符串。你的生成器偶尔会绘制那个零索引元素,它不会对最终字符串的长度产生影响。(副作用是 F 永远不会被绘制。)
  1. 接受 split 具有这种奇怪的行为并与之一起工作:放弃使用 round 的那个令人讨厌的公式。使用 1 + random.nextInt(16) 作为你的索引。

  2. 不要在每次调用 getRandomColor 时重新创建生成器:这破坏了生成器的统计特性。将 random 作为参数传递给 getRandomColor


但是 nextFloat 生成的数字范围在0到1之间,因此您不应该通过乘法得到15.5甚至16。顺便说一句,这不应该抛出索引越界吗? - ctst
@ctst:糟糕,我把split的行为搞反了,并且编造了一个答案来适应它。现在是正确的。 - Bathsheba

2

为了确保您的字符串始终包含6个字符,请尝试使用while替换for循环。请参见以下示例:

while (color.length() <= 6){
    color += letters[random.nextInt(17)];
}

应该是random.nextInt(16) - akash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接