Java 泛型对类的自己的迭代器

Java 泛型对类的自己的迭代器,java,generics,iterator,Java,Generics,Iterator,我正试图为自己的泛型类编写自己的迭代器。我一直在看一些YouTube教程并在网上搜索 import java.util.Iterator; import java.util.NoSuchElementException; public class Pair<T> implements Iterable<T> { private T left; private T right; public Pair(T left, T right){

我正试图为自己的泛型类编写自己的迭代器。我一直在看一些YouTube教程并在网上搜索

import java.util.Iterator;
import java.util.NoSuchElementException;

public class Pair<T> implements Iterable<T> {

    private T left;
    private T right;

    public Pair(T left, T right){
        this.left = left;
        this.right = right;
    }

    public  T getRight(){return this.right;}
    public  T getLeft(){return this.left;}

    // own Iterator
    @Override
    public Iterator<T> iterator() {
        return new myIterator;
    }


    class myIterator implements Iterator<T>{
        T newLeft = null;

        @Override
        public boolean hasNext() {
            if(newLeft == null && Pair.getLeft() != null){
                return true;
            }
            else if(newLeft !=null){
                return Pair.getRight() !=null;
            }
            else {
                return false;
            }
        }
        @Override
        public T next() {
            if(newLeft == null && Pair.getLeft() != null){
                newLeft = Pair.getLeft();
                return newLeft;
            }
            else if(newLeft != null){
                T newRight = Pair.getLeft();
                newLeft = Pair.getRight();
                return newRight;
            }
            throw new NoSuchElementException();
        }
    }
}
import java.util.Iterator;
导入java.util.NoSuchElementException;
公共类对实现了Iterable{
列兵T左;
私权;
公共对(左T,右T){
this.left=左;
这个。右=右;
}
public T getRight(){返回this.right;}
public T getLeft(){返回this.left;}
//自身迭代器
@凌驾
公共迭代器迭代器(){
返回新的myIterator;
}
类myIterator实现了迭代器{
T newLeft=null;
@凌驾
公共布尔hasNext(){
if(newLeft==null&&Pair.getLeft()!=null){
返回true;
}
else if(newLeft!=null){
返回对。getRight()!=null;
}
否则{
返回false;
}
}
@凌驾
公共交通工具{
if(newLeft==null&&Pair.getLeft()!=null){
newLeft=Pair.getLeft();
返回newLeft;
}
else if(newLeft!=null){
T newRight=Pair.getLeft();
newLeft=Pair.getRight();
返回newRight;
}
抛出新的NoTouchElementException();
}
}
}
IntelliJ指出的问题是,我不能像我尝试的那样在迭代器类中使用getLeft和getRight,因为非静态方法不能从静态上下文中引用。我一直在钻研静态和更多,但无法解决这个问题。我是否完全走错了方向,或者至少我的方法有些接近

更新 运行时:

public static void main(String[] args) {
        Pair<Integer> intPair= new Pair(5,1);
        Pair<String> stringPair=new Pair("foo", "bar");

        Iterator<Integer> itr= intPair.iterator();
        while(itr.hasNext()){
            System.out.println(itr.next());
        }
    }
publicstaticvoidmain(字符串[]args){
Pair intPair=新对(5,1);
线对线对=新线对(“foo”、“bar”);
迭代器itr=intPair.Iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
我遇到一个无止境的循环,打印5。所以,迭代器本身可以工作,但我的方法有一个逻辑错误。正在努力,但我感谢您的任何意见。:)

更新2 发现逻辑错误:NewLeft从不更改为null。正在努力解决它

更新3:解决了! 包含嵌入迭代器类的完整Pair类和包含以下调用的main类:

import java.util.Iterator;
import java.util.NoSuchElementException;

public class Pair<T> implements Iterable<T> {

    private T left;
    private T right;

    public Pair(T left, T right){
        this.left = left;
        this.right = right;
    }

    public  T getRight(){return this.right;}
    public  T getLeft(){return this.left;}

    // size of a pair is always 2
    public int size =2;

    // own Iterator
    @Override
    public Iterator<T> iterator() {
        return new myIterator();
    }

    // embedded iterator class
    public class myIterator implements Iterator<T>{
        T newLeft = null;
        T newRight = null;

        @Override
        public boolean hasNext() {
            if(newLeft == null && getLeft() != null){
                return true;
            }
            else if(newLeft !=null && newRight == null){
                newRight=getRight();
                return getRight() !=null;
            }
            else {
                return false;
            }
        }
        @Override
        public T next() {
            if(newLeft == null && getLeft() != null){
                newLeft = getLeft();
                return newLeft;
            }
            else if(newLeft != null && getRight() != null){
                newRight = getRight();
                return newRight;
            }
            throw new NoSuchElementException();
        }
    }
}
import java.util.Iterator;
导入java.util.NoSuchElementException;
公共类对实现了Iterable{
列兵T左;
私权;
公共对(左T,右T){
this.left=左;
这个。右=右;
}
public T getRight(){返回this.right;}
public T getLeft(){返回this.left;}
//一对的大小总是2
公共int size=2;
//自身迭代器
@凌驾
公共迭代器迭代器(){
返回新的myIterator();
}
//嵌入式迭代器类
公共类myIterator实现了迭代器{
T newLeft=null;
T newRight=null;
@凌驾
公共布尔hasNext(){
if(newLeft==null&&getLeft()!=null){
返回true;
}
else if(newLeft!=null&&newRight==null){
newRight=getRight();
返回getRight()!=null;
}
否则{
返回false;
}
}
@凌驾
公共交通工具{
if(newLeft==null&&getLeft()!=null){
newLeft=getLeft();
返回newLeft;
}
else if(newLeft!=null&&getRight()!=null){
newRight=getRight();
返回newRight;
}
抛出新的NoTouchElementException();
}
}
}
主要内容:

import java.util.Iterator;
公共班机{
公共静态void main(字符串[]args){
Pair intPair=新对(5,1);
线对线对=新线对(“foo”、“bar”);
迭代器itr=intPair.Iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
迭代器itrS=stringPair.Iterator();
while(itrS.hasNext()){
System.out.println(itrS.next());
}
}
}

感谢所有帮助我的人,您引导我找到了这个解决方案:)

我猜您想迭代这对中的0到2个可能的值?在迭代器中,您应该引用T的实例。您得到的消息是因为您试图以静态方式成对调用一个方法(即,当Pair是类时,您正在调用Pair.getLeft()

您的初始代码定义了一个变量
T newLeft
,其唯一目的是跟踪是否已使用了left值,由非
null
值表示。使用
boolean
变量会更清楚,即
boolean变量这里。然后,很明显,这个类是不完整的,因为它不跟踪是否使用了正确的值

在您的固定代码中,您有
newLeft
newRight
,这解决了问题,但仍然具有误导性,因为它们的名称和类型都没有表明实际用途。如果将它们更改为
布尔值
变量,则可以设计它们以指示是否存在待定值,例如

final class myIterator implements Iterator<T> { // no need to make this public
    boolean hasPendingLeft = getLeft() != null, hasPendingRight = getRight() != null;

    @Override
    public boolean hasNext() {
        return hasPendingLeft || hasPendingRight;
    }

    @Override
    public T next() {
        if(hasPendingLeft) {
            hasPendingLeft = false;
            return getLeft();
        }
        else if(hasPendingRight) {
            hasPendingRight = false;
            return getRight();
        }
        throw new NoSuchElementException();
    }
}

因此,即使在错误的情况下,这仍然保证了非
null
值,并将抛出一个更有意义的异常。

看起来您需要将
Pair.getLeft()
更改为
getLeft()
Pair.getRight()
更改为
getRight()
更简单:
返回数组.asList(左,右)。迭代器()
@AndyTurner不完全正确,因为这不能处理getRight()或getLeft()返回null的情况。@Eran ok,所以创建一个列表
final class myIterator implements Iterator<T> { // no need to make this public
    boolean hasPendingLeft = getLeft() != null, hasPendingRight = getRight() != null;

    @Override
    public boolean hasNext() {
        return hasPendingLeft || hasPendingRight;
    }

    @Override
    public T next() {
        if(hasPendingLeft) {
            hasPendingLeft = false;
            return getLeft();
        }
        else if(hasPendingRight) {
            hasPendingRight = false;
            return getRight();
        }
        throw new NoSuchElementException();
    }
}
final class myIterator implements Iterator<T> { // no need to make this public
    boolean hasPendingLeft = getLeft() != null, hasPendingRight = getRight() != null;

    @Override
    public boolean hasNext() {
        return hasPendingLeft || hasPendingRight;
    }

    @Override
    public T next() {
        if(hasPendingLeft) {
            hasPendingLeft = false;
            T left = getLeft();
            if(left == null) throw new ConcurrentModificationException();
            return left;
        }
        else if(hasPendingRight) {
            hasPendingRight = false;
            T right = getRight();
            if(right == null) throw new ConcurrentModificationException();
            return right;
        }
        throw new NoSuchElementException();
    }
}