[英]getter setter for Hashmap using generics
我有以下两个类
动物类
class Animal {
Map<String, A> data = new HashMap <String, A>();
public void setValue(HashMap<String, ?> val)
{
this.data = val;
}
public Map getValue()
{
return this.data;
}
}
狗类
class Dog extends Animal {
public void index()
{
Map<String, A> map = new HashMap<String, A>();
map.put("name", "Tommy");
map.put("favfood", "milk"); // want to pass Lists, Integers also
setValue(map);
}
}
正如您从上面的代码中看到的,我试图用index
方法中的键设置一些值,但是我在两个文件中都收到了来自 eclipse 的错误警告。 错误消息是:
在狗类文件中:
Multiple markers at this line
- A cannot be resolved
to a type
- A cannot be resolved
to a type
在动物类文件中:
Multiple markers at this line
- A cannot be resolved to a type
- A cannot be resolved to a type
- Incorrect number of arguments for type Map<K,V>; it cannot be parameterized with arguments
<HashMap<String,A>>
HashMap 中键的数据类型将始终是字符串,但值的数据类型将是随机的,因此我尝试使用泛型。
来自 PHP 背景的我仍然无法掌握 Java 泛型的概念。 你能告诉我代码中的错误在哪里吗?
您不应该为此使用Map
; 这不像 PHP。
相反,您应该创建一个知道每个字段类型的类:
class Animal {
String name;
String favfood;
int someIntegerField;
List<Foo> someListField;
...
}
当所有键和所有值都具有相同类型时,您真的应该只使用Map
。
虽然这种设置不是理想的方法,但一种解决方案是使您的 Map 成为<String, Object>
泛型类型。 通过这种方式,您可以将任何您想要的东西放入对象部分。 但是,将这些信息撤回会很痛苦。 这就是我看到您的课程发生变化的方式。
class Animal {
Map<String, Object> data = new HashMap <String, Object>();
public void setValue(Map<String, Object> map)
{
this.data = map;
}
public Map<String, Object> getValue()
{
return this.data;
}
}
class Dog extends Animal {
public void index()
{
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", "Tommy");
map.put("favfood", "milk"); // want to pass Lists, Integers also
setValue(map);
}
}
A cannot be resolved to a type
这只是意味着您正在使用不存在的“A”类。 例如这里Map<String, A> data
你说的Map<String, A> data
,你正在创建 Map,其中字符串是键,值是类型“A”。
相比之下,这个Map<String, Integer>
意味着你创建了一个映射,它以字符串作为键,整数作为其键的关联值。
您的Map<String, A>
在其声明中具有未定义的类型A
问题是, A
从未被指定,因此不能用作任何类型的类型。
解决方案是使用通配符类型或使用Object
而不是A
。
下面是两个示例解决方案: Map<String, ?> data = new HashMap <String, ?>();
或Map<String, Object> data = new HashMap <String, Object>();
同样的事情必须应用于你的Dog
类中的地图。
问题是你不能只在 Java 泛型中引入一个类型参数并期望它工作。 例如查看Animal
类:
class Animal {
Map<String, A> data = new HashMap <String, A>();
public void setValue(HashMap<String, ?> val)
{
this.data = val;
}
public Map getValue()
{
return this.data;
}
}
类型参数A
未定义,因此在这种情况下,编译器将查找类名A
。 您可以通过为类引入类型参数来解决这个问题:
class Animal<A> { // <--- <A> introduces A as a type parameter
Map<String, A> data = new HashMap <String, A>();
public void setValue(HashMap<String, ?> val)
{
this.data = val;
}
public Map getValue()
{
return this.data;
}
}
然而,问题是,当你初始化一个新的Animal
时,你需要定义A
,例如:
Animal<String> dog = new Animal<>();
dog.setValue("name", "max"); //<---- ok
dog.setValue("age", 13); //<---- won't compile
然而,这意味着您的data
Map 只能从String
映射到String
,您将无法存储整数。
您可以通过使用通配符来解决这个问题,例如:
class Animal {
Map<String, ?> data = new HashMap <String, A>();
public void setValue(HashMap<String, ?> val)
{
this.data = val;
}
public Map getValue()
{
return this.data;
}
}
现在你可以在你的地图中存储从Object
派生的每个数据类型,一个String
甚至一个Integer
。
Animal dog = new Animal();
dog.setValue("name", "max"); //<---- ok
dog.setValue("age", 13); //<---- ok
此解决方案的问题在于您只能以类型保存方式检索此映射中的元素。
dog.getValue().get("name") //<---- ok
Object name = dog.getValue().get("name") //<---- ok
- 但 -
String name = dog.getValue().get("name") //<---- won't compile
到了这个阶段,类型信息已经丢失,你只剩下一个映射String
到Object
映射
请记住,您不应混合使用 Generic type 和 RAW type same 。 我认为最简单的方法是使用Object
而不是A
:
Map<String, Object> data = new HashMap <String, Object>();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.