我有一个非常简单的枚举如下:
public enum Colour {
RED, BLUE, GREEN;
}
这里我放了三种颜色,但它可能有未定义的尺寸。
此枚举将用于可以具有未定义数量的实例(数百,数千甚至数百万)的类。
在这个课程中,我有一个必须返回随机颜色的方法。
我有两种选择。
private Colour[] colours;
public Datastructure() {
colours = Colour.values();
}
public Colour getRandomColour() {
return colours[rand.nextInt() % colours.length];
}
或者我可以继续调用Colour.values()而不是创建颜色列表。
public Colour getRandromColour() {
return Colour.values()[rand.nexInt() % Colour.values().length]
在第一个选项中,创建了一个额外的数组。请记住,此类可能有许多实例,因此可能会被视为浪费内存,并且可能也会影响运行时间(实例化数组)。特别是当有很多类实例时。
在第二个选项中,Colour.values()被调用几次(在这个简单的例子中它只有几次,但在我的项目中它有点复杂并且有更多的调用)所以这可以被认为是浪费CPU使用率。
我更喜欢使用第二个选项,但我很好奇Colour.values()方法的复杂性,我担心这可能是线性O(n)。 n是枚举中的颜色数。当有很多颜色时,这将是可怕的。
或者它只是一个权衡并选择最好的两个邪恶?
tl; dr Enum.values()的复杂性是什么?
答案 0 :(得分:4)
Colour.values()
返回的数组始终包含相同的元素,但values()
每次调用它时都会创建一个 new 数组(所以它是'#1}} O(n)其中n是枚举值的数量。你永远不会修改那个数组。因此,每次需要时调用该方法都是浪费时间。在DataStructure类的每个实例中存储数组都浪费时间和内存。我只需调用该方法一次并将该数组缓存在常量中:
private static final Colour[] COLOURS = colour.values();
public Colour getRandomColour() {
return COLOURS[rand.nextInt(COLOURS.length)];
}
确保此数组永远不会暴露在课堂外。
另请注意Random.nextInt(limit)
的用法完全符合您的要求,可能更快,并且比使用模数更清楚地表达了意图。
答案 1 :(得分:0)
为什么不将缓存的数组放在Color enum本身的静态字段中。然后在Color enum中提供一个方法来返回一个随机条目。
无论如何,Color enum拥有这条数据/方法是有意义的。