我的方法通用参数有什么问题 [英] What is wrong with my method generic parameters

查看:55
本文介绍了我的方法通用参数有什么问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用通用地图填充列表,但是我的代码无法编译.我已经为该问题准备了最简化的示例.在上面有问题的行中的注释中,我已将以下行所产生的错误放入其中.

  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屋!

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