在 java 中迭代 EnumMap 有什么更好的方法?
What is better to iterate over an EnumMap in java?
假设我声明了一个枚举和相应的 emummap 为:
enum MyEnum {
CONSTANT1, CONSTANT2, CONSTANT3;
}
EnumMap<MyEnum, String> MyEnumMap = new EnumMap<MyEnum, String>(MyEnum.class);
我想遍历 MyEnumMap
,例如,只是为了逐个打印每个 Entry
。
在以下情况下迭代键的最佳方法(最快)是什么:
- 当保证
MyEnum
中的每个常量都是MyEnumMap
中的键时
- 当
MyEnum
中的每个常量可能是也可能不是 MyEnumMap
中的键时
我想在使用 MyEnumMap.keySet()
或 MyEnum.values()
的 foreach 循环之间进行选择。任何其他方法都是最受欢迎的。
这取决于您的应用程序逻辑,但这里有一些提示:
对于 1)
// it is a bit faster to iterate over plain array, than over Set
// And you can also get here information about entries that are in enum, but not in hashMap, so you can have logic for those cases.
for (MyEnum e: MyEnum.values()) {
// you can get here information what is contained and not contained in your map
}
对于 2) 但还是使用 1) 更好,因为您可以获得 Map 中不包含的枚举值的信息。
for (MyEnum e: MyEnumMap.keySet()) {
// you can check here all that is in your map, but you cant tell what is in enum but not in your map
}
没关系。在内部,EnumMap
是 implemented,具有一对长度与 enum
条目数相同的数组。一个数组有 enum
个元素,而第二个数组有映射到它们的对象,或 NULL
个占位符。因此,EnumMap
上的任何迭代都等同于遍历整个 enum
序数范围的整数索引上的 for
循环,因此您应该选择使您的代码最易读的方法.
如果你看一下 EnumMap#keySet()
的代码
381 public Set<K> keySet() {
382 Set<K> ks = keySet;
383 if (ks != null)
384 return ks;
385 else
386 return keySet = new KeySet();
387 }
您会注意到它 returns keySet
被 EnumMap
内部用来存储密钥。
现在每次我们调用 MyEnum.values()
时,我们都会得到不同的数组,其中填充了所有枚举元素。这意味着创建第一个空数组,稍后需要用需要一些迭代的所有枚举填充。
因此,在第一种方法中,您将跳过迭代已经由 map 存储的枚举,而在第二种方法中,我们只是创建一些临时数组,它涉及对所有 MyEnum 元素的额外迭代。
也许,您只是想要另一种编写代码的方式....
因为键总是唯一的
for(MyEnum myEnum: MyEnum.values()){
String value = map.get(myEnum);
If(value != null){
//use the value here
}
}
只是另一种写法。
或者你也可以试试
for (Map.Entry<MyEnum, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + "/" + entry.getValue());
}
假设我声明了一个枚举和相应的 emummap 为:
enum MyEnum {
CONSTANT1, CONSTANT2, CONSTANT3;
}
EnumMap<MyEnum, String> MyEnumMap = new EnumMap<MyEnum, String>(MyEnum.class);
我想遍历 MyEnumMap
,例如,只是为了逐个打印每个 Entry
。
在以下情况下迭代键的最佳方法(最快)是什么:
- 当保证
MyEnum
中的每个常量都是MyEnumMap
中的键时 - 当
MyEnum
中的每个常量可能是也可能不是MyEnumMap
中的键时
我想在使用 MyEnumMap.keySet()
或 MyEnum.values()
的 foreach 循环之间进行选择。任何其他方法都是最受欢迎的。
这取决于您的应用程序逻辑,但这里有一些提示:
对于 1)
// it is a bit faster to iterate over plain array, than over Set
// And you can also get here information about entries that are in enum, but not in hashMap, so you can have logic for those cases.
for (MyEnum e: MyEnum.values()) {
// you can get here information what is contained and not contained in your map
}
对于 2) 但还是使用 1) 更好,因为您可以获得 Map 中不包含的枚举值的信息。
for (MyEnum e: MyEnumMap.keySet()) {
// you can check here all that is in your map, but you cant tell what is in enum but not in your map
}
没关系。在内部,EnumMap
是 implemented,具有一对长度与 enum
条目数相同的数组。一个数组有 enum
个元素,而第二个数组有映射到它们的对象,或 NULL
个占位符。因此,EnumMap
上的任何迭代都等同于遍历整个 enum
序数范围的整数索引上的 for
循环,因此您应该选择使您的代码最易读的方法.
如果你看一下 EnumMap#keySet()
381 public Set<K> keySet() {
382 Set<K> ks = keySet;
383 if (ks != null)
384 return ks;
385 else
386 return keySet = new KeySet();
387 }
您会注意到它 returns keySet
被 EnumMap
内部用来存储密钥。
现在每次我们调用 MyEnum.values()
时,我们都会得到不同的数组,其中填充了所有枚举元素。这意味着创建第一个空数组,稍后需要用需要一些迭代的所有枚举填充。
因此,在第一种方法中,您将跳过迭代已经由 map 存储的枚举,而在第二种方法中,我们只是创建一些临时数组,它涉及对所有 MyEnum 元素的额外迭代。
也许,您只是想要另一种编写代码的方式.... 因为键总是唯一的
for(MyEnum myEnum: MyEnum.values()){
String value = map.get(myEnum);
If(value != null){
//use the value here
}
}
只是另一种写法。
或者你也可以试试
for (Map.Entry<MyEnum, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + "/" + entry.getValue());
}