Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将类的迭代器强制转换为其子类的迭代器?_Java_Generics_Collections - Fatal编程技术网

Java 如何将类的迭代器强制转换为其子类的迭代器?

Java 如何将类的迭代器强制转换为其子类的迭代器?,java,generics,collections,Java,Generics,Collections,我试图将一个类的迭代器转换为该类的子类的迭代器。这给了我一个“不可转换类型”错误。为什么这是不可能的,最优雅的解决方法是什么?(或者,如果是这样,为什么这是个坏主意?) 在这种情况下,使用for-each循环不是一个解决方案:我正在尝试实现iterator(),最简单的方法是返回一个类字段的iterator(),但该字段没有确切的所需类型。我也无法更改我的迭代器()的签名 public interface SomeoneElsesInterface { public Iterator&l

我试图将一个类的迭代器转换为该类的子类的迭代器。这给了我一个“不可转换类型”错误。为什么这是不可能的,最优雅的解决方法是什么?(或者,如果是这样,为什么这是个坏主意?)

在这种情况下,使用for-each循环不是一个解决方案:我正在尝试实现
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();
    }
}