【问题标题】:How do I use the class type as a map key and a list of the values of the class as the map value?如何使用类类型作为映射键并将类的值列表用作映射值?
【发布时间】:2016-11-12 21:03:32
【问题描述】:

我在创建 CodeService 接口的实现类时遇到了困难。

public interface CodeService<T extends AbstractCode> {
    Map<Class<T>, List<T>> getCodes();
}

AbstractCode 是我的 Country、City 和 Sex 类的抽象超类,它们在我的数据库中具有相应的表名。

getCodes() 方法应该返回一个类类型的地图作为键(Country.class、City.class、Sex.class),并返回数据库返回的所有国家、城市和性别的列表作为值。

我对@9​​87654323@方法的实现如下:

public class HibernateCodeService<T extends AbstractCode> implements CodeService<T> {
    private Map<Class<T>, List<T>> map = new HashMap<Class<T>, List<T>>();

    public Map<Class<T>, List<T>> getCodes() {

        /* Create an instance of the HibernateCodeDao<Sex> class */
        CodeDao<Sex> sexDao = new HibernateCodeDao<Sex>();

        /* Set the class type as Sex.class */
        Class<Sex> type = Sex.class;

        /* Fetch all the sex values from the database */
        List<Sex> list = sexDao.fetchAll(Sex.class);

        /* Put the Sex.class as the map key, list of sexes as the value */
        map.put(type, list);

        /* Same code for Country and City classes */

        return map;
    }
}

但是,IDE 在map.put(type, list) 行上发出错误。

put (java.lang.Class&lt;T&gt;, java.util.List&lt;T&gt;) in Map cannot be applied to (java.lang.Class&lt;Sex&gt;, java.util.List&lt;Sex&gt;)

我的问题是,如何将类类型存储为我的地图中的键,以便我可以获取该类的所有值的列表?

【问题讨论】:

  • 对于它的价值,这是一个有趣的泛型练习,但至少在实际实践中是非常值得怀疑的。

标签: java hibernate dictionary


【解决方案1】:

如果我要实例化HibernateCodeService&lt;Country&gt; 的实例,那么您的地图将通过您的参数成为Map&lt;Class&lt;Country&gt;, List&lt;Country&gt;&gt;。由于CountrySex 不相关,这意味着它不允许插入到您的地图中。

现在,对于您要完成的任务,您无法使用泛型。因为您的地图的键是Class&lt;T&gt;,这意味着您的地图每个实例只能包含一个可能的值,这在某种程度上违背了地图的目的。虽然我同意@chrylis 的观点,在生产系统中这不是一件好事,但您可以通过从界面中删除泛型来完成您打算完成的任务,并让您的方法返回:

public interface CodeService {
    Map<Class<? extends AbstractCode>, List<? extends AbstractCode>> getCodes();
}

【讨论】:

  • 感谢您的回答,这是我必须创建的一个练习项目,所以除了更好地了解泛型之外,它没有任何用途。 :) 另外,你能解释一下为什么这对于现实生活中的项目来说不是一个好的做法吗?
  • 对于现实生活中的系统来说,这有两个原因。首先,从接口名称中并不清楚特定实现支持哪些类类型,哪些不支持。在AbstractCode 下创建新的子类将变得非常混乱,非常快。其次,任何涉及铸造的事情(必须由该方法的用户完成)通常都是冒险的举动。理想情况下,您的接口应该为它支持的每种返回类型提供一个方法。
  • 关于第二点,实现此接口的正确方法是为每个扩展 AbstractCode 的类提供一个方法并返回该特定类的值列表?
  • 将“实施”一词替换为“设计”,就对了。
猜你喜欢
  • 1970-01-01
  • 2017-08-08
  • 1970-01-01
  • 1970-01-01
  • 2011-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-18
相关资源
最近更新 更多