java 使用泛型的 Hashmap 的 getter setter
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26306147/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
getter setter for Hashmap using generics
提问by black_belt
I have the following two classes
我有以下两个类
Animal Class
动物类
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;
}
}
Dog Class
狗类
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);
}
}
As you can see from the above code I am trying to set some values with keys in index
method, but I am getting error warnings from eclipse in both two files. Error Messages are:
从上面的代码中可以看出,我试图用index
方法中的键设置一些值,但是我在两个文件中都收到了来自 eclipse 的错误警告。错误消息是:
In Dog Class File:
在狗类文件中:
Multiple markers at this line
- A cannot be resolved
to a type
- A cannot be resolved
to a type
In Animal Class File :
在动物类文件中:
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>>
The data type of the keys in HashMap will always be a String but the data types of values would be random, hence I am trying to use Generics.
HashMap 中键的数据类型将始终是字符串,但值的数据类型将是随机的,因此我尝试使用泛型。
Coming from PHP background I still haven't been able to grasp the concept of Java Generics. Could you please tell me where is the mistake in my code?
来自 PHP 背景的我仍然无法掌握 Java 泛型的概念。你能告诉我代码中的错误在哪里吗?
回答by Louis Wasserman
You should notbe using a Map
for this; this is not like PHP.
你不应该Map
为此使用 a ;这不像 PHP。
Instead you should be creating a class that knows the type of each of its fields:
相反,您应该创建一个知道每个字段类型的类:
class Animal {
String name;
String favfood;
int someIntegerField;
List<Foo> someListField;
...
}
You should really only be using a Map
when all the keys and all the values have the same type.
Map
当所有键和所有值都具有相同类型时,您真的应该只使用 a 。
回答by Chris Franklin
While this kind of setup is not the ideal way to go, one solution is to make your Map a <String, Object>
generic type. In this way you can put whatever you want into the Object part. This will, however, be a pain to pull that information back out. This is how I see your classes changing.
虽然这种设置不是理想的方式,但一种解决方案是使您的 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);
}
}
回答by Chief_Gokhlayeh
Your Map<String, A>
has the undefined type A
in its declaration.
The problem is, that A
is never specified and therefore can not be used as a Type for anyting.
您Map<String, A>
的A
声明中有未定义的类型。问题是,它A
从未被指定,因此不能用作任何类型的类型。
The solution would be to either use the wildcard typeor use Object
instead of A
.
该解决方案将是要么使用通配符类型或使用Object
代替A
。
Here are the two example solutions:
Map<String, ?> data = new HashMap <String, ?>();
or
Map<String, Object> data = new HashMap <String, Object>();
以下是两个示例解决方案:
Map<String, ?> data = new HashMap <String, ?>();
或
Map<String, Object> data = new HashMap <String, Object>();
The same thing has to be applied to the map in your Dog
class.
同样的事情必须应用于您Dog
班级中的地图。
回答by PeterK
The problem is that you can't just introduce a type parameter in Java generics and expect it to work. For example looking at the Animal
class:
问题是你不能只在 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;
}
}
Type parameter A
is not defined, so in this case, the compiler will look for a class name A
. You can solve that by introducing a type parameter for the class:
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;
}
}
However the problem with this is, that you then need to define A
when you initialise a new Animal
for example:
但是,问题在于,您需要A
在初始化新Animal
对象时进行定义,例如:
Animal<String> dog = new Animal<>();
dog.setValue("name", "max"); //<---- ok
dog.setValue("age", 13); //<---- won't compile
What this means however, is that your data
Map can only map from String
to String
, you will not be able to store integers.
然而,这意味着您的data
Map 只能映射 fromString
到String
,您将无法存储整数。
You could get around this by using wildcards, like this for example:
您可以通过使用通配符来解决这个问题,例如:
class Animal {
Map<String, ?> data = new HashMap <String, A>();
public void setValue(HashMap<String, ?> val)
{
this.data = val;
}
public Map getValue()
{
return this.data;
}
}
Now you can store every data type derived from Object
in your map, a String
or even an Integer
.
现在,您可以存储从Object
地图中派生的每种数据类型,aString
甚至Integer
.
Animal dog = new Animal();
dog.setValue("name", "max"); //<---- ok
dog.setValue("age", 13); //<---- ok
The problem with this solution is that you are only to retrieve the elements in this map in a type save manner.
此解决方案的问题在于您只能以类型保存方式检索此映射中的元素。
dog.getValue().get("name") //<---- ok
Object name = dog.getValue().get("name") //<---- ok
-- but --
- 但 -
String name = dog.getValue().get("name") //<---- won't compile
As by this stage, the type information has been lost and you are left with a map that maps String
to Object
到了这个阶段,类型信息已经丢失,剩下的映射String
到Object
回答by libik
A cannot be resolved to a type
It just means that you are using class "A" which does not exist. For example here Map<String, A> data
you are saying, that you are creating Map, where string is key and the value is type "A".
这只是意味着您正在使用不存在的“A”类。例如,Map<String, A> data
您在这里说的是,您正在创建 Map,其中字符串是键,值是类型“A”。
In comparision, this Map<String, Integer>
would mean, that you create map, which has string as key and integer as associated value to its key.
相比之下,这Map<String, Integer>
意味着您创建了映射,该映射将字符串作为键,将整数作为键的关联值。