Reputation: 95
I have two methods, one returns a HashMap of <Integer,String>
and the other returns a HashMap of <Integer, Spanned>
. Is there a way of using generics to make them into just one method?
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;
}
and if so, how would I instantiate and call them? Currently I'm doing it this way (from another class):
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);
Upvotes: 1
Views: 205
Reputation: 32086
This uses a single map, requires no explicit casting, but does require knowing the type for each key. Maybe not a perfect fit, but maybe this gives you some ideas to build the right solution? Hope it helps,
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{}
}
So you have three options:
Map<Integer,Object>
, jkschneider's solutionMap<Integer,<? extends MyBaseClass>>
, where Spanned
and a String
-like class extends MyBaseClass
Upvotes: 0
Reputation: 27757
Since there is no commonality in the inheritance tree of Spanned
and String
, you would have to alter the methods to return Map<Integer, Object>
and then could:
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();
}
This kind of defeats the purpose of generics of course, but serves to shine a light on the true problem here.
Of course it seems far better to rewrite the whole thing to something like the following. The only difference between the two functions is the Html.forHtml(..)
call. Let's assume for a moment (without loss of generality) that you really want the String
and not 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;
}
Perhaps you don't really need queryGMGAppText()
at all. Are you calling it in so many places that it is important to have this convenience method?
Upvotes: 1