Java-如何解决enumMap 应用map接口的三难问题

发布于 2017-01-17 14:55:43 字数 1155 浏览 1137 评论 1

请输入图片描述

Map<UserORM, Object> map1 = null;
Map<? extends Enum<?>, Object> map2;
Map<Enum<? extends Enum<?>>, Object> map3 = null;

map1 = new EnumMap<UserORM, Object>(UserORM.class);// OK
map2 = new EnumMap<UserORM, Object>(UserORM.class);// OK
map3 = new EnumMap<UserORM, Object>(UserORM.class);//Type mismatch: cannot convert from EnumMap<UserORM,Object> to Map<Enum<? extends Enum<?>>,Object>

map1.put(UserORM.id, "EQ");// OK
map2.put(UserORM.id, "EQ");//The method put(capture#11-of ? extends Enum<?>, Object) in the type Map<capture#11-of ? extends Enum<?>,Object> is not applicable for the arguments (UserORM, String)
map3.put(UserORM.id, "EQ");// OK

// 想要利用map接口让程序更加灵活
// map1接口不够通用,我的其他枚举没法放入,所以舍弃这个方案
// map2接口定义非常符合预期,也可以使用enumMap这个实现,但是却无法进行put操作
// map3接口为了弥补map2无法put操作,但是却无法使用enumMap实现
// 请问,想要利用enumMap实现,同时给出一个通用map的接口,在java中有无合适的方案

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

想挽留 2017-08-18 00:35:41

EnumMap java doc:
"All of the keys in an enum map must come from a single enum type that is specified, explicitly or implicitly, when the map is created."
EnumMap的键值一定是单个enum型的实例. 所以你这里想把 不同的enum的实例做键值 放入一个 EnumMap里就错了.

看一下EnumMap的代码可以知道, 它内部维护了一个数组来记录Map的value, 数组大小为 某个Enum的实例总数. 而根据键值(Enum实例)的put/get则是, 根据Enum实例的ordinal值读出/写入数组的对应下标:

public V get(Object key) {
return (isValidKey(key) ?
unmaskNull(vals[((Enum)key).ordinal()]) : null);
}
public V put(K key, V value) {
typeCheck(key);
int index = key.ordinal();
Object oldValue = vals[index];
vals[index] = maskNull(value);
if (oldValue == null)
size++;
return unmaskNull(oldValue);
}

所以这里更可以看出, 为什么EnumMap的键值一定是单个Enum型的实例了.

更新

再回到你的问题看看这两个错误:

map3 = new EnumMap<UserORM, Object>(UserORM.class);//Type mismatch: cannot convert from EnumMap<UserORM,Object> to Map<Enum<? extends Enum<?>>,Object>

map2.put(UserORM.id, "EQ");//The method put(capture#11-of ? extends Enum<?>, Object) in the type Map<capture#11-of ? extends Enum<?>,Object> is not applicable for the arguments (UserORM, String)

给出代码详细说明一下:

enum E1{A,B,C,D}
enum E2{A,B,C,D}
@Test
public void test11(){
Map<Enum<? extends Enum<?>>,Object> map3=new HashMap<>();
// Map<Enum<? extends Enum<?>>,Object> map3=new EnumMap<E1,Object>(E1.class);
map3.put(E2.A, new Object());
map3.put(E1.A, new Object());

Map<?, Object> map2=new HashMap<>();
map2.put("sdf", new Object()); //出错, method put.. is not applicable...
}

1). 这里用HashMap定义出来的map3和new EnumMap<E1,Object>(E1.class)是不一样的, 前者可以接受任意Enum(E1.A和E2.A)来作为key; 后者只能用E1来做key;
2). 为什么报method put.. is not applicable..., 参见Effective Java, item23, "you can’t put any element (other than null) into a Collection<?>." 也就是说Map<?, Object>是无法加入新的item的. 这里这么理解, ?代表你不知道或者不关心用什么类型来做key; 编译器为了类型安全, 禁止向此map中添加新元素.

更新
可以看出这里不应该给出一个EnumMap, 而应该使用HashMap<BaseORMConstants>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文