我的方法通用参数有什么问题 [英] What is wrong with my method generic parameters
问题描述
我想用通用地图填充列表,但是我的代码无法编译.我已经为该问题准备了最简化的示例.在上面有问题的行中的注释中,我已将以下行所产生的错误放入其中.
void populateList(List< ;?扩展Map< String,?>>列表){list.clear();HashMap< String,?>地图;map = new HashMap< String,String>();//类型为HashMap的put(String,capture#2-of?)方法< String,capture#2-of?>不适用于参数(字符串,字符串)map.put("key","value");//此行不编译//方法add(capture#3-of?扩展Map< String,?>)的类型为List< capture#3-of?扩展Map< String,?>不适用于参数(HashMap< String,capture#5-of?>)list.add(map);//此行不编译}
为什么会这样?有我不明白的东西吗?
编辑1
根据下面的答案之一,他指出了什么?代表未知类型,而不是Object的后代.这是有道理的.而且,在方法内部,我知道映射的类型,因此我相应地修改了我的简单代码.
void populateList(List< ;?扩展Map< String,?>>列表){list.clear();HashMap< String,String>地图;//已知类型map = new HashMap< String,String>();map.put("key","value");//此行现在可以编译//方法add(capture#3-of?扩展Map< String,?>)的类型为List< capture#3-of?扩展Map< String,?>不适用于参数(HashMap< String,capture#5-of?>)list.add(map);//此行STILL不会编译.这是为什么?}
我问这的原因是因为android SDK的一种方法期望这样的列表,而且似乎无法填充这样的列表.如何做到这一点?类型转换?
编辑2
由于有一些更改我的签名的建议,所以我会补充说我不能这样做.基本上,我想填充SimpleExpandablaListAdapter的列表.
void test(){ExpandableListView expandableListView.setAdapter(new ArrayAdapterRetailStore(this,R.layout.list_item_retail_store,retailStores));;列表< ;?扩展Map< String,?>groupData = new ArrayList< HashMap< String,String>>>();populateGroup(groupData)//为了简单起见,省略了子数据expandableListView.setAdapter(新的SimpleExpandableListAdapter(这个,组数据,R.layout.list_group,新的String [] {"GroupKey"},新的int [] {R.id.tvGroupText},childData,R.layout.list_item_child,新的String [] {"ChildKey"},新的int [] {R.id.tvChilText}));}//我希望populateGroupData()是通用的void populateGroupData(List<?extended Map< String,?>> groupData){groupData.clear();HashMap< String,String>地图;map = new HashMap< String,String>();map.put("key","value");groupData.add(map);//不编译}
来自文档
当实际类型参数为?时,表示某些未知类型.我们传递来添加的任何参数都必须是该未知类型的子类型.由于我们不知道是什么类型,因此无法传递任何内容.唯一的例外是null,它是每种类型的成员.
因此,您只能添加
list.add(null);
请在通用通配符
I want to populate a List with generic maps, but my code does not compile. I have prepared the most simplified example for the problem. In the comments above problematic lines I have put the error the line below produces.
void populateList(List<? extends Map<String,?>> list) {
list.clear();
HashMap<String, ?> map;
map = new HashMap<String,String>();
//The method put(String, capture#2-of ?) in the type HashMap<String,capture#2-of ?> is not applicable for the arguments (String, String)
map.put("key", "value"); // this line does not compile
// The method add(capture#3-of ? extends Map<String,?>) in the type List<capture#3-of ? extends Map<String,?>> is not applicable for the arguments (HashMap<String,capture#5-of ?>)
list.add(map); //This line does not compile
}
Why is this so? Is there something I do not understand?
EDIT 1
According to one of the answers below in which he pointed out that ? stands for unknown type and not a descendant of Object. This is a valid point. And also, inside the method I know the type which go into map so I have modified my simple code accordingly.
void populateList(List<? extends Map<String,?>> list) {
list.clear();
HashMap<String, String> map; //known types
map = new HashMap<String,String>();
map.put("key", "value"); // this line now compiles
// The method add(capture#3-of ? extends Map<String,?>) in the type List<capture#3-of ? extends Map<String,?>> is not applicable for the arguments (HashMap<String,capture#5-of ?>)
list.add(map); //This line STILL does not compile. Why is that?
}
The reason I am asking this is because a method form android SDK expects such list and as it seems one cannot populate such lists. How does one do that? Typecast?
EDIT 2
Since there several proposals to change my signature I will add that I cannot do that. Basicaly, I would like to populate lists for SimpleExpandablaListAdapter.
void test() {
ExpandableListView expandableListView.setAdapter(new ArrayAdapterRetailStore(this, R.layout.list_item_retail_store, retailStores));
List<? extends Map<String, ?>> groupData= new ArrayList<HashMap<String,String>>();
populateGroup(groupData)
// child data ommited for simplicity
expandableListView.setAdapter( new SimpleExpandableListAdapter(
this,
groupdata,
R.layout.list_group,
new String[] {"GroupKey"},
new int[] {R.id.tvGroupText},
childData,
R.layout.list_item_child,
new String[] {"ChildKey"},
new int[] {R.id.tvChilText}));
}
// I want populateGroupData() to be generic
void populateGroupData(List<? extends Map<String,?>> groupData) {
groupData.clear();
HashMap<String,String> map;
map = new HashMap<String,String>();
map.put("key", "value");
groupData.add(map); // does not compile
}
From the documentation
When the actual type parameter is ?, it stands for some unknown type. Any parameter we pass to add would have to be a subtype of this unknown type. Since we don't know what type that is, we cannot pass anything in. The sole exception is null, which is a member of every type.
so, you can add only
list.add(null);
Please read this tutorial on Generics Wildcards
这篇关于我的方法通用参数有什么问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!