消费者LT; T>映射类< T>在HashMap中 [英] Consumer<T> mapped Class<T> in HashMap

查看:316
本文介绍了消费者LT; T>映射类< T>在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&GT;映射类&lt; T&gt;在HashMap中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆