展平列表列表 - 转换类型不匹配

时间:2013-06-14 01:48:25

标签: java list type-conversion

我正在实现一个迭代器来展平列表列表,但是它给了我一个错误,我无法理解它为什么会发生:

错误是: 类型不匹配:无法从java.util.Iterator<java.util.List<T>>转换为java.util.Iterator<java.util.List<T>>

我很困惑,为什么要尝试将类型转换为自身?为什么不成功?是因为它被用在内部类中吗?

public class FlattenList<T> implements Iterable<T>{
    private List<List<T>> lists;
    public FlattenList(List<List<T>> list){
        this.lists = list;
    }
    public Iterator<T> iterator(){
        return new ListIterator();
    }
    class ListIterator<T> implements Iterator<T>{
        private Iterator<List<T>> listsiterator;
        private Iterator<T> listiterator;
        public ListIterator(){
            if (lists != null)
                listsiterator = lists.iterator(); // The conversion mismatch here
            }
        }
            //..
    }
}

2 个答案:

答案 0 :(得分:2)

您的代码中实际上有两种不同的类型参数。两者都被称为T,因此内部阴影会影响外部。但他们绝对不一样。您的代码等同于:

public class FlattenList<T> implements Iterable<T>{
    private List<List<T>> lists;
    public FlattenList(List<List<T>> list){
        this.lists = list;
    }
    public Iterator<T> iterator(){
        return new ListIterator();
    }
    class ListIterator<E> implements Iterator<E>{
        private Iterator<List<E>> listsiterator;
        private Iterator<E> listiterator;
        public ListIterator(){
            if (lists != null) {
                listsiterator = lists.iterator(); // The conversion mismatch here
            }
        }
        //..
    }
}

会产生稍微有用的错误消息:

  

类型不匹配:无法从java.util.Iterator&lt; java.util.List&lt; T&gt;&gt;转换到java.util.Iterator&lt; java.util.List&lt; E&gt;&gt;

解决方案不是重新声明类型变量。由于ListIterator是一个内部类,因此它可以访问包含实例的T

public class FlattenList<T> implements Iterable<T>{
    private List<List<T>> lists;
    public FlattenList(List<List<T>> list){
        this.lists = list;
    }
    public Iterator<T> iterator(){
        return new ListIterator();
    }
    class ListIterator implements Iterator<T>{
        private Iterator<List<T>> listsiterator;
        private Iterator<T> listiterator;
        public ListIterator(){
            if (lists != null) {
                listsiterator = lists.iterator(); // The conversion mismatch here
            }
        }
        //..
    }
}

答案 1 :(得分:1)

T类中删除类型参数ListIterator可以解决您的问题。即:

class ListIterator implements Iterator<T> {

即使这两个类型的参数被称为相同(T),它们实际上相同。这就是为什么你会收到如此令人困惑的消息:java.util.List<List<T>> cannot be cast to java.util.List<List<T>>因为那两个T,我再说一遍,不一样。

这也可以解决问题:

public Iterator<T> iterator(){
    return new ListIterator(lists);
}
class ListIterator<T> implements Iterator<T>{
    private Iterator<List<T>> listsiterator;
    private Iterator<T> listiterator;
    public ListIterator(List<List<T>> listOfLists){
        if (listOfLists != null)
            listsiterator = listOfLists.iterator(); // The conversion mismatch here
        }
    }
}