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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 09:40:40  来源:igfitidea点击:

getter setter for Hashmap using generics

javagenerics

提问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 indexmethod, 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 Mapfor 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 Mapwhen 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 Ain its declaration. The problem is, that Ais 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 Objectinstead 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 Dogclass.

同样的事情必须应用于您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 Animalclass:

问题是你不能只在 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 Ais 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 Awhen you initialise a new Animalfor 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 dataMap can only map from Stringto String, you will not be able to store integers.

然而,这意味着您的dataMap 只能映射 fromStringString,您将无法存储整数。

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 Objectin your map, a Stringor 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 Stringto Object

到了这个阶段,类型信息已经丢失,剩下的映射StringObject

回答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> datayou 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>意味着您创建了映射,该映射将字符串作为键,将整数作为键的关联值。