“可迭代不能转换到列表” - 是不是`List`类型`Iterable`的?

问题描述:

我叫了getElements方法返回Iterable<Element>“可迭代<Element>不能转换到列表<Element>” - 是不是`List`类型`Iterable`的?

我这样做:

List<Element> elements = (List<Element>) getElements(); 

这会产生错误:

java.lang.ClassCastException: com.utesy.Element$3 
cannot be cast to java.util.List 

我想到了一个List是一个类型的Iterable

+1

发布的'的getElements()的代码;'方法 – 2010-10-18 13:58:09

+1

的'List'接口扩展了'Iterable'接口 - 所以是的,'List'就像你说的那样,类型是'Iterable'。但这并不意味着'getElements'返回的'Iterable'也是'List'。所有列表都是可打断的,但并非所有的可打印列表都是列表。 – 2010-10-18 14:01:01

是返回List<Element>List<T>延伸Iterable<T>,但这并不意味着你可以从任何Iterable<T>List<T>投 - 只有当值实际上是指的一个实例类型为List<T>。这是完全可能实现Iterable<T>没有实现List<T>接口的休息...在这种情况下,你会期待发生什么呢?

简而言之,让我们将Iterable<T>更改为ObjectList<T>StringString延伸Object,所以你可以尝试Object转换为String ...但如果参考实际上String(或为空),中投将只在执行时取得成功。

并非所有Iterable s为List S,因而它不是安全投任意IterableList

采取任何Set例如,一个HashSetIterable但是元素没有顺序,因此它无法实现List接口,因此是不是List

+2

''“但元素没有顺序,所以它不是'List'” - 这不是'HashSet'不是'List'的原因。 'HashSet'不是'List',因为它没有实现'List'接口。 '' – 2010-10-18 14:03:46

+0

@Matt Ball,真的......重新表达了一下......更好? :) – aioobe 2010-10-18 14:26:49

从异常消息显然 Iterable<Element>不强制转换为List<Element>

,所以你需要从getElements()

列表扩展集这又扩展可迭代。因此,您试图将其转换为不能工作的子类型,除非getElements()实际上正在返回一个List(该签名不以任何方式保证)。

参见:http://download.oracle.com/javase/1.5.0/docs/api/java/util/List.html

List子接口Iterable含义列表中包括了可迭代有几乎一切,但不是周围的其他方式。因此,不是List实例中的所有方法在Iterable中都有相同的方法。

尽量避免那种铸造的。

我会建议你采取快速浏览一下Java 6 API和覆盖铸造

List<Element>是一种类型的Iterable<Element>的教程,但是,这并不意味着所有Iterable<Element>对象是List<Element>对象。您可以投List<Element>作为Iterable<Element>,但不是相反。

苹果是一种水果,但这并不意味着所有的水果都是苹果。你可以把苹果当成水果,但不能反过来。

+13

+1没有229k代表 – willcodejavaforfood 2010-10-18 14:06:43

List实现Iterable接口,但这并不意味着Iterable可以转换回List。 Iterable更通用,可能是Hash或一些与List没有任何关系的外来类型。 (它看起来像getElements()返回一个匿名内部类的实例,它与类中的getElements一起包含)。

如果getElements会碰巧包含Lists,那么这将是一个有效的强制转换。由于getElements()返回的类型实际上不是List,所以会产生运行时错误。

+0

列表实现了Iterable,并且这个*确实意味着它可以投射到它。 OP所面临的问题正在以另一种方式发生。这与它是一个实现还是扩展无关。 – 2010-10-18 14:11:33

+0

对不起,“不代表它可以投它”不清楚,我已经填写了“它”,所以它不能被错误地解释,因为你有。 – AshirusNW 2010-10-18 14:15:34

你可以把可迭代成一个列表与

List<Element> elements = Lists.newArrayList(getElements()); 
+13

...其中Lists是com.google.common.collect.Lists。 – jarnoan 2011-10-14 09:33:17

+0

这是最简洁的方法。否则,你需要一个很长的实现:-( - 或者只是使用Scala;) – 2011-11-04 20:05:18

为什么不:

Iterable<Element> i = ...; //is what you have 
    List<Element> myList = new LinkedList<Element>(); 
    for (Element e:i) { 
     myList.add(e); 
    } 

? 不需要谷歌图书馆。

+0

到目前为止最简单的方法... – 2017-07-13 09:53:59

,你可以尝试把与instanceof保护:

if (AnElement instanceof AList){ 
    //cast 
    AList = (AnList)Element 
}