在调用枚举

时间:2015-08-02 17:33:22

标签: java random enums

我正在创建一个用于生成分形的应用程序,而且我只是坚持一件事。该程序要求两种颜色:一种用于背景,一种用于分形。所以我做了一个颜色的枚举:

public class Property {
    public enum Color {

        WHITE(new java.awt.Color(255, 255, 255).getRGB()),
        BLACK(new java.awt.Color(0, 0, 0).getRGB()),
        BLUE(new java.awt.Color(110, 124, 255).getRGB()),
        GREEN(new java.awt.Color(121, 206, 30).getRGB()),
        RED(new java.awt.Color(255, 58, 36).getRGB()),
        YELLOW(new java.awt.Color(254, 255, 57).getRGB()),
        ORANGE(new java.awt.Color(255, 133, 46).getRGB()),
        PURPLE(new java.awt.Color(206, 27, 255).getRGB()),
        PINK(new java.awt.Color(255, 40, 166).getRGB()),
        RANDOM(Utils.randomColor()),

        @Override
        public String toString() {
            return this.name().toLowerCase();
        }

        private int color;

        Color(int color) {
            this.color = color;
        }

        public int getRGB() {
            return this.color;
        }
    }
}

randomColor()方法如下所示:

public class Utils {
    private static final Random RANDOM = new Random();

    public static int randomColor() {
        int r = RANDOM.nextInt(256);
        int g = RANDOM.nextInt(256);
        int b = RANDOM.nextInt(256);
        return new java.awt.Color(r, g, b).getRGB();
    }
}

但是我注意到随机颜色实际上只创建了一次,因此两种颜色都是相同的,显然不是所需的输出。如何在每次调用Property.Color.RANDOM时生成两种不同的颜色?

4 个答案:

答案 0 :(得分:3)

初始化Color枚举后,RANDOM将是一种特定颜色 - 它可能与执行不同,但在一次运行中,它将保持不变。

每次使用RANDOM时,您想要生成新的颜色。 (至少这是我理解它的方式)一种方法是使用一个特定于常量的枚举体:

public enum Color {
    //...
    RANDOM(0) {
        @Override
        public int getRGB() {
            return Utils.randomColor();
        }
    };

    //...
}

这有其自身的问题。例如,您可能希望生成多个随机颜色,每个颜色保持不变。否则,每次使用颜色时,都会得到一个新颜色。为了避免这种情况,唯一的方法就是根本不使用枚举,至少不是唯一的。基本上,解决方案是执行java.awt.Color已经执行的操作:一个可以创建任意实例的简单类,以及枚举某些预定义颜色的public static final常量。

答案 1 :(得分:2)

其他答案可行,但在Java 8中,有一种更好的方法。每个枚举的初始化不是它的颜色,而是IntSupplier<Color>

public class Property {
    ...
    Property(IntSupplier rgbSupplier) {
        this.rgbSupplier = rgbSupplier;
    }

    Property(int rgb) {  // convenience constructor
        this(() -> rgb); // delegate to constructor above
    }

    public int getRGB() {
        return rgbSupplier.getAsInt();
    }
    ...
}

对于大多数颜色,结构是相同的;但对于随机的,您提供方法参考:

    ...
    PINK(new java.awt.Color(255, 40, 166).getRGB()),
    RANDOM(Utils::randomColor),
    ...

在英语中,这样做是构建每个枚举而不是具有特定值,但使用IntSupplier表示&#34;给我价值。&#34; &#34;标准&#34;每个类型都使用IntSupplier构建,并始终返回提供的值(() -> rgb),但随机类型使用调用IntSupplier的{​​{1}}构建。

答案 2 :(得分:1)

要解决此问题,只需重新定义getRGB()枚举值为RANDOM的方法。这是整个代码:

public class Property {
    public enum Color {

        WHITE(new java.awt.Color(255, 255, 255).getRGB()),
        BLACK(new java.awt.Color(0, 0, 0).getRGB()),
        BLUE(new java.awt.Color(110, 124, 255).getRGB()),
        GREEN(new java.awt.Color(121, 206, 30).getRGB()),
        RED(new java.awt.Color(255, 58, 36).getRGB()),
        YELLOW(new java.awt.Color(254, 255, 57).getRGB()),
        ORANGE(new java.awt.Color(255, 133, 46).getRGB()),
        PURPLE(new java.awt.Color(206, 27, 255).getRGB()),
        PINK(new java.awt.Color(255, 40, 166).getRGB()),
        RANDOM(0) {
            @Override
            public int getRGB() {
                return Utils.randomColor();
            }
        };

        @Override
        public String toString() {
            return this.name().toLowerCase();
        }

        private int color;

        Color(int color) {
            this.color = color;
        }

        public int getRGB() {
            return this.color;
        }
    }
}

单个枚举值可以覆盖方法实现,就像它在子类中完成的那样。在这里,我们将RANDOM值用于每次都返回新的随机颜色(忽略color字段,它只是设置为0)。

答案 3 :(得分:0)

枚举只会初始化一次。 RANDOM(Utils.randomColor())之上的代码不是方法,而是枚举的值。每次访问RANDOM时都不会打电话。调用randomColor()方法生成随机颜色而不是分配给RANDOM枚举。