Java 如何将类的迭代器强制转换为其子类的迭代器?
我试图将一个类的迭代器转换为该类的子类的迭代器。这给了我一个“不可转换类型”错误。为什么这是不可能的,最优雅的解决方法是什么?(或者,如果是这样,为什么这是个坏主意?) 在这种情况下,使用for-each循环不是一个解决方案:我正在尝试实现Java 如何将类的迭代器强制转换为其子类的迭代器?,java,generics,collections,Java,Generics,Collections,我试图将一个类的迭代器转换为该类的子类的迭代器。这给了我一个“不可转换类型”错误。为什么这是不可能的,最优雅的解决方法是什么?(或者,如果是这样,为什么这是个坏主意?) 在这种情况下,使用for-each循环不是一个解决方案:我正在尝试实现iterator(),最简单的方法是返回一个类字段的iterator(),但该字段没有确切的所需类型。我也无法更改我的迭代器()的签名 public interface SomeoneElsesInterface { public Iterator&l
iterator()
,最简单的方法是返回一个类字段的iterator()
,但该字段没有确切的所需类型。我也无法更改我的迭代器()
的签名
public interface SomeoneElsesInterface {
public Iterator<SomeoneElsesInterface> iterator();
}
public abstract class MyAbstractClass implements SomeoneElsesInterface {
final MyAbstractClass[] things;
public MyAbstractClass(SomeoneElsesInterface... things) {
this.things = (MyAbstractClass[]) things;
}
}
public class MyClass extends MyAbstractClass {
public MyClass(MyAbstractClass thing1, MyAbstractClass thing2) {
super(thing1, thing2);
}
public Iterator<SomeoneElsesInterface>() {
return (Iterator<SomeoneElsesInterface>) Arrays.asList(things).iterator();
}
}
公共接口SomeoneseInterface{
公共迭代器迭代器();
}
公共抽象类MyAbstractClass实现SomeoneseInterface{
最终MyAbstractClass[]事物;
公共MyAbstractClass(SomeoneseInterface…things){
this.things=(MyAbstractClass[])things;
}
}
公共类MyClass扩展了MyAbstractClass{
公共MyClass(MyAbstractClass thing1,MyAbstractClass thing2){
超级(thing1,thing2);
}
公共迭代器(){
return(Iterator)array.asList(things.Iterator();
}
}
当然,我可以改变
事物的类型。但是,如果是那样的话,我需要在其他地方进行大量的石膏成型。我知道我的构造函数不会被非MyAbstractClass
s的对象调用,但无论如何我不能更改接口。对每个循环使用,而不是迭代器
每个
的都是从Java 1.5
有关更多详细信息,请参阅此链接:
每个示例的Java(补充Kumar答案):
List strings=new ArrayList();
字符串。添加(“一”);
字符串。添加(“两个”);
字符串。添加(“三”);
用于(字符串项:字符串){
系统输出打印项次(项);
}
从你的问题来看,我想你是在尝试这样做:
Iterator<Object> original = ...
Iterator<String> converted = (Iterator<String>)original;
class IterableThing implements Iterable<Foo> {
private Collection<Bar> someStuff;
public Iterator<Foo> iterator() {
return (Iterator<Foo>)someStuff.iterator();
}
}
class Bar {
}
class Foo extends Bar {
}
如果someStuff
可以保证只包含Foo
的实例,那么您是否可以将someStuff
声明为集合
而不是集合
?如果不是,那么只返回someStuff
的迭代器就没有意义了,因为它可能包含非Foo
的内容
我想你需要考虑一下你能做出什么样的保证。如果您不能保证someStuff
只包含Foo
s,那么您可能需要维护自己的状态,或者根据需要过滤someStuff
的内容
编辑:您已使用代码更新了问题。太棒了
看起来您实际上是在尝试返回类型的超类上的迭代器。这让事情变得容易多了
在您的特定情况下,您可能可以通过以下方法解决此问题:
return Arrays.<SomeoneElsesInterface>asList(things).iterator();
返回数组.asList(things).iterator();
它将生成一些警告,但这没关系,因为您知道您已经保证了类型安全。如果将Arrays.asList(things)
更改为Arrays.asList((someoneseinterface[])things)
?一旦数组被强制转换为正确的类型,列表和迭代器将随之出现。这看起来就像使用以下命令一样简单:
公共类MyClass扩展了MyAbstractClass{
// ...
公共迭代器迭代器(){
返回Arrays.asList(things.iterator();
}
}
问题在于,Arrays#asList()
推断您需要类型为list
的列表,这将生成类型为iterator
的迭代器。由于迭代器
的类型参数不是协变的,因此在需要迭代器的情况下,不能提供迭代器
。通过强制数组#asList()
创建类型为list
的列表,如上所示,您还可以从调用Iterable#iterator()
返回预期的迭代器类型
SomeoneseInterface
的作者会更友好地将其iterator()
方法的返回类型指定为iterator类的类型和所包含字段的类型之间的关系是什么(如果有的话)?你能给我们看一些代码吗?基本上是的。然而在我的例子中,original
实际上是子类
的一个迭代器
,我希望转换成子类
的一个超类的迭代器
。因此,我可以保证,original只包含(可传递的)类实例的元素。
return Arrays.<SomeoneElsesInterface>asList(things).iterator();
public class MyClass extends MyAbstractClass {
// ...
public Iterator<SomeoneElsesInterface> iterator() {
return Arrays.<SomeoneElsesInterface>asList(things).iterator();
}
}