Java HashMaps中的异构类型获取

Java HashMaps中的异构类型获取,java,hashmap,Java,Hashmap,是否可能有一个HashMap,它接受一个统一的键(比如“String”类型),但其值是不同的。例如,考虑哈希表 m < /强>。 我需要以下功能: m.get("UID1"); // This fetches a String value m.get("UID2"); // This fetches another type like a class instance 然后,根据获取的值的类型,可以进行进一步的处理。您可以执行以下操作: HashMap<String,

是否可能有一个HashMap,它接受一个统一的键(比如“String”类型),但其值是不同的。例如,考虑哈希表<强> m < /强>。 我需要以下功能:

    m.get("UID1"); // This fetches a String value 
    m.get("UID2"); // This fetches another type like a class instance

然后,根据获取的值的类型,可以进行进一步的处理。

您可以执行以下操作:

HashMap<String, Object> m = new HashMap<>();

//Retreive a string:
String myString = (String) m.get("UID1");

//Retreive a variable of any type
MyType variable = (MyType) m.get("UID2");
HashMap m=newhashmap();
//检索字符串:
String myString=(String)m.get(“UID1”);
//检索任何类型的变量
MyType变量=(MyType)m.get(“UID2”);
或者,如果可能,可以将hashmap的类型设置为所需的类型,如果需要字符串,可以执行toString()

例如:

HashMap<String, MyObject> m = new HashMap<>();

//Retreive the string representation of your object:
String myString = m.get("UID1").toString();

//Retreive the object:
MyObject object = m.get("UID2");
HashMap m=newhashmap();
//检索对象的字符串表示形式:
字符串myString=m.get(“UID1”).toString();
//检索对象:
MyObject对象=m.get(“UID2”);

如果您想使用字符串作为键,您将失去类型安全性,而且无法避免。您只需放弃编译器拥有的所有信息,您将被迫自己手动提供这些信息

相反,您可以对同样包含类型信息的字符串使用某种包装类。通过这种方式,您可以获得合理的类型安全性

下面是Foo类的一个示例,它包装了HashMap并提供了类型安全的put和get方法:

public class Foo {

static class TypedKey<T> {
    final Class<T> clazz;
    final String id;
    public TypedKey(Class<T> clazz, String id) {
        this.clazz = clazz;
        this.id = id;
    }
    @Override
    public int hashCode() {
        return id.hashCode();
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof TypedKey)) {
            return false;
        }
        return id.equals(((TypedKey<?>) obj).id);
    }
    @Override
    public String toString() {
        return id;
    }
}

static final TypedKey<String> STRING_KEY = new TypedKey<>(String.class, "String");
static final TypedKey<Integer> INTEGER_KEY = new TypedKey<>(Integer.class, "Integer");

public static void main(String[] args) {
    Foo foo = new Foo();

    foo.put(STRING_KEY, "bar");
    String bar = foo.get(STRING_KEY);

    foo.put(INTEGER_KEY, 42);
    int baz = foo.get(INTEGER_KEY);

    foo.put(STRING_KEY, 42);
}

final Map<TypedKey<?>, Object> map = new HashMap<>();

public <T> void put(TypedKey<T> key, T value) {
    map.put(key, value);
}

@SuppressWarnings("unchecked")
public <T> T get(TypedKey<T> key) {
    return (T) map.get(key);
}

}
公共类Foo{
静态类TypedKey{
最后一节课;
最终字符串id;
公共TypedKey(类clazz,字符串id){
this.clazz=clazz;
this.id=id;
}
@凌驾
公共int hashCode(){
返回id.hashCode();
}
@凌驾
公共布尔等于(对象obj){
if(this==obj){
返回true;
}
如果(!(类型dkey的obj实例)){
返回false;
}
返回id.equals((TypedKey)obj.id);
}
@凌驾
公共字符串toString(){
返回id;
}
}
静态最终类型KEY STRING_KEY=新类型KEY(STRING.class,“STRING”);
静态最终TypedKey INTEGER_KEY=新的TypedKey(INTEGER.class,“INTEGER”);
公共静态void main(字符串[]args){
Foo-Foo=新的Foo();
foo.put(字符串键,“bar”);
stringbar=foo.get(String\u键);
foo.put(整数_键,42);
intbaz=foo.get(整数_键);
foo.put(字符串_键,42);
}

final Map考虑使用类作为键,而不是Sting。这将为您提供以类型安全的方式进行操作的机会,正如Joshua Bloch所描述的“类型安全异构容器”:


但是,这只会在每个类型只有一个值的情况下起作用。

那么
Map
如何呢?不过,您必须在阅读后转换这些值。您想如何使用/处理它?您可以设置
Map
,其中
type
是一个Iterface。然后您可以添加它的不同实现。或者
Map
不是您想要的请给我们更多的细节和例子,你想要什么do@elbraulio您可以设置映射,其中类型为Iterface但是,您将无法添加任何内置类型作为映射值,如
字符串
字符
等。@Aomine您可以给出一个需要该功能的示例吗?也许
映射
不是solution@elbraulio
Map
是解决方案,但它必须是
Map正如@ernest_kThanks@Donat所建议的。是的,每种类型使用一个值
public static class Container {
  private Map<Class<?>, Object> store = new HashMap<>();

  public <T> void put(Class<T> type, T value) {
    store.put(Objects.requireNonNull(type), value);
  }

  public <T> T get(Class<T> type) {
    return type.cast(store.get(type));
  }
}
Container container = new Container();

container.put(String.class, "test");
container.put(Integer.class, Integer.valueOf(5));

String s = container.get(String.class);
Integer i = container.get(Integer.class);