【问题标题】:incompatiable types error when returning generics wildcard collection返回泛型通配符集合时出现不兼容类型错误
【发布时间】:2016-03-10 05:30:33
【问题描述】:

我正在研究一个生成从数据库中获取的两级关联数组的函数。该数组将用于创建可展开的列表视图。它必须是泛型通配符List,因为可扩展列表适配器需要它。

我刚刚从another thread 中读到,为了将元素添加到泛型集合中,superextend 必须与泛型一起使用。它可以正常工作,但是,为什么在返回集合时会出现类型不兼容的错误?

public HashMap<String, List<? super SearchField>> getAll() {

    HashMap<String, List<SearchField>> listCollection = new HashMap<String,List<SearchField>>();

    /************DataBase Query***************/    
    try {

        if (cursor.moveToFirst()) {

            List rowList = new ArrayList<SearchField>();

            do {

                SearchField sf = new SearchField();

                sf.value = cursor.getString(cursor.getColumnIndex("value"));

                sf.group_title = cursor.getString(cursor.getColumnIndex("group_title"));

                sf.key = cursor.getString(cursor.getColumnIndex("key"))

                rowList.add(sf);

                Map<String,String> group = (Map<String,String>)listCollection.get(sf.group_title);

                if(group == null){

                    listCollection.put(sf.group_title,rowList);

                }else{

                    listCollection.get(sf.group_title).add(sf);

                }


            } while(cursor.moveToNext());
        }
    } catch (Exception e) {
    } finally {
        if (cursor != null && !cursor.isClosed()) {
            cursor.close();
        }
    }
    return listCollection;
           ^^^^^^^^^^^^^
}

搜索字段类

public class SearchField {

    public String value;

    public String key;

    public String group_title;


}

我从另一个线程中遵循了这个示例:

  public List<? extends Foo> getFoos()
  {
    List<Foo> foos = new ArrayList<Foo>(); /* Or List<SubFoo> */
    foos.add(new SubFoo());
    return foos;
  }

我试图从获取的结果中创建的两级数组在 PHP 中是这样的:

$group = array("A Group"=>array("value"=>2,"title"=>"Apple"),
               "B Group"=>array("value"=>1,"title"=>"Boy")
         )

更新:

我想返回通配符的原因是我的可扩展列表适配器用于不同的活动并采用不同结构的集合。

public ExpandableListAdapter(FragmentActivity context, List<String> group,
        Map<String, List<?>> listCollection) {
    this.dataCollections = listCollection;
}

所以我想为适配器返回一个使用通配符的列表。

【问题讨论】:

  • 您必须提供调用 getAll() 方法的代码部分。
  • 你能改变getAll声明让它返回Map&lt;String, List&lt;SearchField&gt;&gt;吗?老实说,通配符似乎毫无意义。顺便说一句,catch (Exception e) {},oof。永远,永远,永远这样做。至少输入e.printStackTrace(); 这样你至少知道 是否抛出异常。 (为什么要捕获并吃掉所有个异常?没有理由这样做。始终尽可能捕获最具体的异常。)
  • 您必须提供调用 getAll() 方法的代码部分。
  • (Map&lt;String,String&gt;)listCollection.get(sf.group_title) 这就是我要说的。请注意,listCollection 中的值声明为 List,因此您显然在此处将List 转换为Map。这将抛出一个 ClassCastException,你的空 catch 块正在吃它。

标签: java android generics


【解决方案1】:

我认为问题在于您定义 rowList 的方式。试试这个:

List<SearchField> rowList = new ArrayList<SearchField>();

而不是

List rowList = new ArrayList<SearchField>();

【讨论】:

  • 你说raw types should not be used是对的,但这不会导致编译错误。
  • 你是对的,至少不应该导致编译错误。你可以试试 HashMap> listCollection = new HashMap>();而不是 HashMap> listCollection = new HashMap>();
  • 这将解决编译错误,但我认为这不会使他们的代码工作,根据我的其他 cmets。 ;) 我什至不确定他们是否首先需要通配符。我猜这不会阻止你把它放在你的答案中。
【解决方案2】:

您是否尝试过在函数声明中使用List&lt;? extends SearchField&gt;

【讨论】:

  • 这并不能解决编译错误,它改变了代码的含义。见PECS
猜你喜欢
  • 2021-04-15
  • 1970-01-01
  • 2019-09-06
  • 2015-10-04
  • 2017-04-16
  • 2011-04-18
  • 2020-12-16
  • 1970-01-01
  • 2011-08-26
相关资源
最近更新 更多