消费者LT; T>映射类< T>在HashMap中 [英] Consumer<T> mapped Class<T> in HashMap
问题描述
我想创建 IdentityHashMap< Class< T>,Consumer< T>>
。基本上,我想用一种方法来映射一个类型,说明如何处理这种类型。
我想动态地用对象X来说,执行Y. I可以做
private IdentityHashMap< Class<?>,Consumer<>> interceptor = new IdentityHashMap<>();
但它很糟糕,因为在使用它时我必须在lamba中投射对象。
示例:
interceptor.put(Train.class,train - > {
System.out.println(((Train)train).getSpeed());
});
我想要做的是
私人< T> IdentityHashMap< Class< T>,Consumer< T>> interceptor = new IdentityHashMap<>();
但似乎不允许。有没有办法做到这一点 ?使用这种类型的方法映射类型的最佳解决方法是什么?
这基本上就像类型安全异构容器,可能最初由Joshua Bloch描述,但不能使用 Class
来投射结果。
奇怪的是,我找不到一个很好的例子,所以这里是一个:
package mcve;
import java.util。*;
import java.util.function。*;
class ClassToConsumerMap {
private final Map< Class<?>,Consumer<>> map =
new IdentityHashMap<>();
public< T>消费与LT ;?超T> (Class< T>密钥,Consumer< ;? super T> c){
@SuppressWarnings(unchecked)
最终消费者< ;?超T>旧=
(消费者< ;? super T>)map.put(key,c);
返回旧的;
}
public< T>消费与LT ;?超T> get(Class< T> key){
@SuppressWarnings(unchecked)
final Consumer< ;?超T> c =
(Consumer<?super T>)map.get(key);
return c;
$ b如果有必要使用泛型类型,比如 Consumer< List< String>>
,那么您需要使用类似Guava TypeToken
因为 Class 只能表示一种类型的擦除。
Java泛型的局限性有一个令人讨厌的地方,那就是其中的一个不能一般地编写,因为没有办法做,例如:
class ClassToGenericValueMap< V> {
...
public< T> V氮化T> put(Class< T> key,V< T> val){...}
public< T> V氮化T> get(Class< T> key){...}
}
无论如何,如何做到这一点。
另外,Guava有一个 ClassToInstanceMap
当您需要 Map< Class< T> ;, T>
。
I want to create an IdentityHashMap<Class<T>, Consumer<T>>
. Basically, I want to map a type with a method saying what to do with this type.
I want to dynamically be able to say with objects X, execute Y. I can do
private IdentityHashMap<Class<?>, Consumer<?>> interceptor = new IdentityHashMap<>();
but it sucks because then I have to cast the object in the lamba when using it.
Example:
interceptor.put(Train.class, train -> {
System.out.println(((Train)train).getSpeed());
});
What I would like to do is
private <T> IdentityHashMap<Class<T>, Consumer<T>> interceptor = new IdentityHashMap<>();
But it doesn't seem to be allowed. Is there a way to do this ? What is the best workaround to map types with a method for this type ?
解决方案 This is essentially just like the type-safe heterogeneous container, perhaps originally described by Joshua Bloch, except you can't use the Class
to cast the result.
Weirdly, I can't find a great example existing on SO, so here is one:
package mcve;
import java.util.*;
import java.util.function.*;
class ClassToConsumerMap {
private final Map<Class<?>, Consumer<?>> map =
new IdentityHashMap<>();
public <T> Consumer<? super T> put(Class<T> key, Consumer<? super T> c) {
@SuppressWarnings("unchecked")
final Consumer<? super T> old =
(Consumer<? super T>) map.put(key, c);
return old;
}
public <T> Consumer<? super T> get(Class<T> key) {
@SuppressWarnings("unchecked")
final Consumer<? super T> c =
(Consumer<? super T>) map.get(key);
return c;
}
}
If it's necessary to use generic types, like Consumer<List<String>>
, then you need to use something like Guava TypeToken
because Class
can only represent the erasure of a type.
One annoying thing about the limitations of Java's generics is that one of these can't be written generically, because there's no way to do e.g.:
class ClassToGenericValueMap<V> {
...
public <T> V<T> put(Class<T> key, V<T> val) {...}
public <T> V<T> get(Class<T> key) {...}
}
Anyhow, that's how to do this sort of thing.
As a side note, Guava has a ClassToInstanceMap
for when you need a Map<Class<T>, T>
.
这篇关于消费者LT; T>映射类< T>在HashMap中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!