假设我有一个如下所示的枚举:
public enum Utils {
UTIL_1, UTIL_2, ... UTIL_n
}
现在,我有Set<Utils> myUtils
,其中包含一堆这些枚举条目。其他一些模块(我没有任何控制权)为我提供了一个这样的实用程序名称(例如“ UTIL_i
”)作为String。我需要检查它是否包含在集合myUtils
中。有什么方法可以在O(1)中执行此操作吗?我了解,我可以将集合更改为一组字符串,然后对此做一个 .contains(),但我想保留它作为最后的选择。
更新:
按照答案中的建议,我尝试了一个小实验。我创建了一个小代码段来生成一个Java文件,其中包含一个固定大小的枚举。我尝试使用大小1000、2500、5000。大小为10000的枚举向我显示了错误The code for the static initializer is exceeding the 65535 bytes limit
在Eclipse中的解释,该错误here。我创建了一个集合myUtils
并将所有元素从枚举推到该集合。对于每种不同大小的myUtils
,我执行了1000次代码段,看起来像myUtils.contains(Utils.valueOf(<elementName>))
。该代码段的平均执行时间(以毫秒为单位)如下:
枚举大小= 1000
UTIL_1 search duration = 1704ms
UTIL_500 search duration = 2316ms
UTIL_1000 search duration = 1732ms
枚举大小= 2500
UTIL_1 search duration = 2326ms
UTIL_1250 search duration = 1886ms
UTIL_2500 search duration = 1860ms
枚举大小= 5000
UTIL_1 search duration = 2569ms
UTIL_2500 search duration = 2709ms
UTIL_5000 search duration = 2361ms
它清楚地表明Enum.valueOf(String element)
的平均执行时间随枚举的大小而增加,但是我不确定这种方法的时间复杂度。
答案 0 :(得分:2)
您可以通过Utils
将字符串转换为实际的Utils util = Utils.valueOf(String)
成员,然后通过myUtils.contains(util)
检查字符串是否包含在集合中,该AFAIK是O(1)运算。
当然,如果您获得的字符串实际上与任何Utils
不对应,则应该检查异常。在您的示例中,它不是,因为它应该像枚举名称一样是大写。
public enum Utils {
UTIL_1, UTIL_2, ... UTIL_n
}
//...
String utilName = someOtherModuleRoutine();
try {
if (myUtils.contains(Utils.valueOf(utilName))) {
// found!
} else {
// not found :(
}
} catch (IllegalArgumentException e) {
// utilName is not an actual Utils name
}
答案 1 :(得分:1)
其中一种选择是使用valueOf
的{{1}}方法,但是时间复杂度取决于您将要使用的输入。
如果大多数输入不可转换为enum
枚举,则进行Utils
并使用set
方法作为contains
方法是最好的方法不适用于不可转换的值。
答案 2 :(得分:0)
我建议您扩展Enum以添加其他模块中的字符串标识符。另外,我将编写一种将String转换为Util枚举的方法。
public enum Utils {
UTIL_1("Utils_1"),
UTIL_2("Utils_2"),
UTIL_3("Utils_3");
private final String name;
private Utils(final String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public static Utils of(final String name) {
if (name != null) {
for (final Utils util : Utils.values()) {
if (util.getName().equals(name)) {
return util;
}
}
}
return null;
}
}
要使用枚举集合,应使用EnumSet或EnumMap。然后您可以执行以下操作:
public static void main(final String[] args) {
final String utilName = "Utils_1";
final Utils utilFromModule = Utils.of(utilName);
final Set<Utils> utils = EnumSet.of(Utils.UTIL_1, Utils.UTIL_2);
utils.contains(utilFromModule);
}