如何在HashMap中使用泛型?

时间:2013-12-03 02:29:47

标签: java generics

我有两个方法,一个返回<Integer,String>的HashMap,另一个返回<Integer, Spanned>的HashMap。有没有办法使用泛型将它们变成一种方法?

public static Map<Integer, Spanned> queryGMGText() throws ParseException {
    ParseQuery<ParseObject> positionQuery = ParseQuery.getQuery("AndroidGMGContent");
    positionQuery.whereExists("position");
    List<ParseObject> ParsePositionResult = positionQuery.find();

    final Map<Integer,Spanned> appText = new HashMap<Integer,Spanned>();

    for (int i = 0; i < ParsePositionResult.size(); i++) {
        appText.put(ParsePositionResult.get(i).getInt("position"), Html.fromHtml(ParsePositionResult.get(i).getString("appText")));
    }

    return appText;
}

public static Map<Integer, String> queryGMG(String field) throws ParseException {
    ParseQuery<ParseObject> positionQuery = ParseQuery.getQuery("AndroidGMGContent");
    positionQuery.whereExists("position");
    List<ParseObject> ParsePositionResult = positionQuery.find();

    final Map<Integer,String> fieldMap = new HashMap<Integer,String>();

    for (int i = 0; i < ParsePositionResult.size(); i++) {
        fieldMap.put(ParsePositionResult.get(i).getInt("position"), ParsePositionResult.get(i).getString(field));
    }

    return fieldMap;
}

如果是这样,我将如何实例化并调用它们?目前我正在这样做(来自另一个班级):

Map<Integer,Spanned> appTextMap = new HashMap<Integer,Spanned>();
    try {
        appTextMap = ParseContent.queryGMGText();
    } catch (ParseException e) {
        e.printStackTrace();
    }
// now I can use it, i.e.
Spanned s = appTextMap.get(1);

2 个答案:

答案 0 :(得分:1)

严格回答问题:

由于SpannedString的继承树中没有共性,因此您必须更改方法以返回Map<Integer, Object>,然后才能:

try {
    Map<Integer, Object> appTextMap = ParseContent.queryGMGText();
    // now I can use it, i.e.
    Spanned s = (Spanned) appTextMap.get(1);
} catch (ParseException e) {
    e.printStackTrace();
}

这种当然违背了仿制药的目的,但却有助于揭示真正的问题。

重新考虑原始代码:

当然,将整个事情重写为以下内容似乎要好得多。这两个函数之间的唯一区别是Html.forHtml(..)调用。让我们暂时(不失一般性)假设你真的想要String而不是Spanned

public static Map<Integer, String> queryGMGAppText() throws ParseException {
    return queryGMG("appText");
}

public static Map<Integer, String> queryGMG(String field) throws ParseException {
    ParseQuery<ParseObject> positionQuery = ParseQuery.getQuery("AndroidGMGContent");
    positionQuery.whereExists("position");
    List<ParseObject> ParsePositionResult = positionQuery.find();

    final Map<Integer,String> fieldMap = new HashMap<Integer,String>();

    for (int i = 0; i < ParsePositionResult.size(); i++) {
        fieldMap.put(ParsePositionResult.get(i).getInt("position"), ParsePositionResult.get(i).getString(field));
    }

    return fieldMap;
}

也许你根本不需要queryGMGAppText()。你是否在很多地方打电话给这种便利方法很重要?

答案 1 :(得分:0)

这使用单个地图,不需要显式转换,但需要知道每个键的类型。也许不是一个完美的契合,但也许这给你一些想法来构建正确的解决方案?希望它有所帮助,

public class CustomMap {

      private Map<String, Object> _map;

      public CustomMap(){
         _map = new HashMap<String, Object>();  
      }  

      public <T> void setTypeValueByKey(Integer key, T value) {
         _map.put(key.toString(), value);
      }

      public <T> T getTypeValueByKey(Class<T> klass, Integer key) {
         return klass.cast(_map.get(key.toString()));
      }

      public static void main(String[] o){
         CustomMap map = new CustomMap();
         map.setTypeValueByKey(new Integer(1), new Spanned() );
         map.setTypeValueByKey(new Integer(2), new String("foo"));         

         Spanned spanned = 
           map.getTypeValueByKey(Spanned.class, new Integer(1));
         String foo = 
           map.getTypeValueByKey(String.class, new Integer(2));                  
      }

   static class Spanned{}
}

所以你有三个选择:

  • 使用Map<Integer,Object>,jkschneider解决方案
  • 进行显式投射
  • 上述解决方案的各个方面
  • 或,Map<Integer,<? extends MyBaseClass>>,其中SpannedString - 类扩展MyBaseClass