Java 泛型对类的自己的迭代器
我正试图为自己的泛型类编写自己的迭代器。我一直在看一些YouTube教程并在网上搜索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){
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();
}
}