Java:制作一个Map<>变量泛型

时间:2014-08-22 11:27:00

标签: java generics

我需要将变量和值存储在某处,我倾向于使用Map。问题是值的类型会有所不同,所以我认为应该使用泛型。所以我试过这样的事情:

Map<String, T> netPara;

当然它不起作用,然后我尝试了

Map<String, Object> netPara;

这有效但当我重新获得值时,它只返回Object类型,而不是“boolean”,“int”。

任何人都可以帮助我吗?我相信它往往很简单,但我还不是专家。提前谢谢。

实际上我有一个接收参数列表的函数A,但是它的函数B也会使用这些参数但B的参数列表是vide,所以我希望将它们存储为类参数并由函数B重用所以这就是我所做的:

Class Person() {
Map<String, T> infoPaire; // if I use Object to replace T
Function A: receiver(boolean b, int i, String1 st1, String2 st2) {
    infoPaire.put("b", b);
    infoPaire.put("i", i);
    infoPaire.put("st1", st1);
    infoPaire.put("st2", st2);
}

Function B: user() {
    boolean b = infoPaire.get("b"); // I need to add (boolean) to cast and I dont want it, it's ugly
    int i = infoPaire.get("i");
    String st1 = infoPaire.get("st1");
    String st2 = infoPaire.get("st2");
}

7 个答案:

答案 0 :(得分:3)

需要将

T定义为类或方法的泛型参数。

方法

public <T> Map<String, T> getMap(){
    return new HashMap<String, T>();
}

public class Test <T> {

    public Map<String, T> getMap(){
        return new HashMap<String, T>();
     }
}

用法

方法

使用方法时

Test t = new Test();
Map<String, Double> m = t.<Double>getMap();

或更简洁,

Map<String, Double> m = t.getMap();

由于Double可以从右侧推断出来。

上课。

Test<String> t = new Test<String>;

或使用类型推断,

Test<String> t = new Test<>;

Map<String, Integer> m = t.getMap()

总之,

Test<String> t = new Test<>;
Map<String, String> m = t.getMap();
Test<Integer> t2 = new Test<>;
Map<String, Integer> m2 = t2.getMap();

警告

对于类型推断内容,即<>t.getMap()没有类型参数,您必须使用Java 7或更高版本。

关于一般类型系统的其他警告

使用泛型允许您创建操作值的代码而不知道它们是什么,但有一些警告。参考你的问题,听起来你可能试图在Map中存储两个不同类型的值,就像这样,

m.put('int', 7)
m.put('bool', true)

这是不可能的。因为T虽然是通用的,但最终必须解析为类的一个类型。例如,

Map<String, Integer> m;

此地图只能 持有 Integer 值。

Object声明为值的原因是因为 Java中的每个类都是Object的子类,因此任何东西都可以进入。 但是使用Object是非常糟糕的设计。你本质上是关闭类型系统,这是像Java这样的语言带来的主要优势之一表,静态打字。

因此,如果您发现自己想要存储一组同质值,则可能需要重新考虑您的设计。即使在明确允许此类事物的语言(方案,python,JavaScript等)中,通常也会以均匀的方式使用它们,这是设计缺陷的标志。

答案 1 :(得分:0)

您可以将其中一种类型设置为类型参数,但是您还必须将其声明为类型参数。只给它一个单字母的名称,例如T,不会自动使它成为类型参数。

class MyClass<T> {   // Note: T is a type parameter
    private Map<String, T> netPara;

    // ...
}

答案 2 :(得分:0)

你可以期待的最好的是一种对象的值和一个有不安全的强制转换的类型化的getter方法:

class VariableMap extends HashMap<String, Object> {
   public <T> T getValue(Object key) {
       return (T)super.get(key);
   }
{

答案 3 :(得分:0)

您需要先了解generictype-casting。 就你的问题而言,Object Class在继承中处于顶层,意味着Object是所有java类的父类。

因此,您可以将任何对象强制转换为Object类,但是当您需要将对象放回其实际类中时,您必须将其强制转换。比如String str = (String) netPara.get(key);

您需要研究多态,转换和通用概念。 Generic来解决你现在面临的问题。

答案 4 :(得分:0)

以下是将元素放入地图检查一次的方法

 public class TakingInput {

public static void main(String[] args) {

Map<String,Object> map=new HashMap<String,Object>();

Integer in=new Integer(123);

Object obj=in;

String s=new String("suresh");

Object obj2=s;

map.put("hi",obj);

map.put("ramesh",obj2);

System.out.println(map);

  //to retrive 

 String ss=(String) map.get("ramesh"); //type casting

System.out.println(ss); //o/p:suresh


}

 }

答案 5 :(得分:0)

你想要像

这样的东西
BigDecimal n = dictionary.get("n");
String s = dictionary.get("s");

可能有

class Dictionary {
    public <T> T get(String name) { ... }

由于类型擦除(编译/运行时代码不再知道泛型类型),无法执行此操作,将对象强制转换为T。

解决方案:

BigDecimal n = dictionary.get(BigDecimal.class, "n");
String s = dictionary.get(String.class, "s");

可以使用运行时强制转换异常来实现:

public class Dictionary {
    private Map<String, Object> map = new HashMap<>();

    public <S> S put(Class<S> type, String name, S value) {
        Object oldValue = map.put(name, value);
        return type.cast(oldValue);
    }

    public <T> T get(Class<T> type, String name) {
        Object value = map.get(name);
        return type.cast(value);
    }
}

可以存储类型本身,可能作为附加键,Map<Class<?>, Map<String, Object>>>,但在这个过于开放的问题上下文中仍然没有获得太多。

答案 6 :(得分:0)

我现在看到你问的问题与我原先想的略有不同。我会留下我的另一个答案,因为它解释了为什么这是一个问题。

由于您只处理StringsBooleansIntegers,因此只需将Strings存储在您的Map中即可。稍后转换为合适的类型。

Map<String, String> m = new HashMap<>();
m.put("bool", "true");
m.put("int", "1");

Integer i = Integer(m.get("int"));
Boolean b = Boolean(m.get("bool"));

这将是伪安全,但您必须在代码中的其他位置跟踪值的类型。

可能最好的解决方案是使用三个Maps,每种类型一个。

Map<String, String> stringMap;
Map<String, Integer> intMap;
Map<String, Boolean> boolMap;

一般来说,有三张地图确实没什么坏处。

为什么你不能干净地使用一张地图,请参阅我对这个问题的另一个答案。