我正试图权衡使用EnumMapa的优缺点HashMap.因为,我将一直在寻找使用a String,似乎HashMap用一把String钥匙将是正确的选择.然而,EnumMap似乎更好的设计,因为它传达了我将密钥限制为特定枚举的意图.思考?
这是一个虚构的例子,展示了我将如何使用Map:
enum AnimalType { CAT, DOG }
interface Animal {}
class Cat implements Animal {}
class Dog implements Animal {}
public class AnimalFactory {
private static final Map<AnimalType, Animal> enumMap
= new EnumMap<AnimalType, Animal>(AnimalType.class);
// versus
private static final Map<String, Animal> stringMap
= new HashMap<String, Animal>();
static {
enumMap.put(AnimalType.CAT, new Cat());
enumMap.put(AnimalType.DOG, new Dog());
stringMap.put("CAT", new Cat());
stringMap.put("DOG", new Dog());
}
public static Animal create(String …Run Code Online (Sandbox Code Playgroud) 我最近了解了EnumMap在Java中的优点,并希望将现有的替换ImmutableMap<OccupancyType, BigDecimal>为EnumMap.但是,我也喜欢ImmutableMap提供的不可变属性.
EnumMap<K extends Enum<K>, V> 在 Java 中,按照相关枚举的定义明确排序,正如您在 javadoc 中看到的:
枚举映射以其键的自然顺序(声明枚举常量的顺序)维护。这反映在由集合视图返回的迭代(keySet(),entrySet(),和values())。
我需要的是SortedMap使用枚举作为键类型。我想使用headMap()or 之类的方法firstKey(),但我想从EnumMaps增加的 cpu+memory 性能中获利。一个TreeMap听起来像是太多的开销在这里。
问题:这是否只是在实现中遗漏了,是懒惰(源自AbstractMap)还是有充分的理由为什么EnumMap不是SortedMap?
我需要静态初始化 EnumMap。我知道两种方法。
使用Map的of()方法
private static final Map<<EnumKey>, <Value>> TEST_MAP = Map.of(ENUM_CONST1, "Value1", ENUM_CONST2, "Value2");
Run Code Online (Sandbox Code Playgroud)
使用双括号初始化
private static final Map<<EnumKey>, <Value>> TEST_MAP = new EnumMap<>(EnumKey.class) {
{
put(ENUM_CONST1, "Value1");
put(ENUM_CONST2, "Value2");
}
};
Run Code Online (Sandbox Code Playgroud)
还有其他更干净、更高效的方法吗?
我有一个枚举类:
enum class E { A, B, C, D }
Run Code Online (Sandbox Code Playgroud)
初始化包含所有 E 值作为键且每个初始值为 0 的 EnumMap 的最简洁方法是什么?
val map = ...?
assert(map is EnumMap<E, Int>)
assert(map[E.A] == 0)
assert(map[E.B] == 0)
assert(map[E.C] == 0)
assert(map[E.D] == 0)
Run Code Online (Sandbox Code Playgroud)
我能想到的最简洁的是:
val map = E.values().associateWithTo(EnumMap(E::class.java)) { 0 }
Run Code Online (Sandbox Code Playgroud)
然而,名称的重复E打破了 DRY 原则。而且这个词associateWithTo有点拗口。有没有更简洁易读的方式?我希望有这样的EnumMap.allOf()东西EnumSet.allOf()。
我试图在抽象方法中使用通用的EnumMap作为参数.我的问题是,当我使用EnumMap的现有枚举实现抽象方法时,编译器告诉我必须删除Override Annotation并实现super方法.
这是我的抽象类:
import java.util.EnumMap;
import java.util.HashMap;
public abstract class AbstractClazz {
// The methode I tried to define
public abstract <K extends Enum<K>> boolean isVisible(EnumMap<K, Object> visibleConditions);
// second test
public abstract <K> boolean isVisible2(HashMap<K, Object> visibleConditions);
// third test
public abstract boolean isVisible3(EnumMap<?, Object> visibleConditions);
}
Run Code Online (Sandbox Code Playgroud)
而实施班:
import java.util.EnumMap;
import java.util.HashMap;
public class Clazz extends AbstractClazz {
public enum Numbers {
ONE, TWO, THREE
}
// Error: The method isVisible(EnumMap<Clazz.Numbers,Object>) of type Clazz must override or implement a …Run Code Online (Sandbox Code Playgroud) 我想弄清楚如何反序列化一个 EnumMap。到目前为止,我一直在将 Gson 库用于其他所有方面,并且取得了成功。事实证明这很困难。
这是一个基本的想法:
import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;
import com.google.gson.Gson;
enum FRUIT {
APPLE, BANANA
}
EnumMap<FRUIT, String> fruitMap;
Gson gson = new Gson();
public void setFruitMap(String jsonString){
Type typeToken = new TypeToken<EnumMap<FRUIT, String>>(){}.getType();
fruitMap = gson.fromJson(jsonString, typeToken);
}
String fruitMapString = "{ \"BANANA\":\"tasty!\", \"APPLE\":\"gross!\" }";
setFruitMap(fruitMapString); //Error occurs here.
assertEquals("tasty!", fruitMap.get(FRUIT.BANANA));
Run Code Online (Sandbox Code Playgroud)
当我运行上面的代码时,我得到一个 java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to java.util.EnumMap
所以在我看来,Gson 库并没有创建 EnumMap,而是在创建 LinkedHashMap 后尝试进行转换。
所以我想我会去制作我自己的反序列化逻辑。下面是一个执行工作。但是..它有点笨拙。
public JsonDeserializer<EnumMap<FRUIT, String>> deserializeFruitMap(){
return new JsonDeserializer<EnumMap<FRUIT, String>>(){
@Override
public EnumMap<FRUIT, …Run Code Online (Sandbox Code Playgroud) 鉴于我有必要
import java.awt.Color;
import java.util.EnumMap;
Run Code Online (Sandbox Code Playgroud)
和
enum Terrain { ... }
Run Code Online (Sandbox Code Playgroud)
那么就我从文档中可以看出,这应该有效
static EnumMap<Terrain, Color> colors = new EnumMap<Terrain, Color>(Terrain.class);
Run Code Online (Sandbox Code Playgroud)
但它实际上给了我这个错误
cannot find symbol
symbol : constructor EnumMap()
location: class java.util.EnumMap<Terrain,java.awt.Color>
static EnumMap<Terrain,Color>colors=new EnumMap<Terrain, Color>();
Run Code Online (Sandbox Code Playgroud)
我错过了什么?