簡體   English   中英

迭代器返回錯誤的整數值

[英]Iterator returns wrong integer values

我必須實現Incrementer類,並且必須實現Iterable

輸出應為:

1 2 3 4 5 6 7 8 9 10 
1 3 5 7 9 
10 9 8 7 6 5 4 3 2 1 
10 9 8 7 6 5 4 3 2 1 
1 2 3 4 6 8 10 
1 2 3 4 5 6 7 8 6 4 2 
10 9 8 7 6 5 6 7 8 9 10

我得到:

2 3 4 5 6 7 8 9 10 
3 5 7 9 11 
9 8 7 6 5 4 3 2 1 

2 3 4 6 8 10 
2 3 4 5 6 7 8 
9 8 7 6 5 6 7 8 9 10 

我的Incrementer類如下所示:

    package in;

import java.util.Iterator;

public class Incrementer implements Iterable<Integer> {
    int val, step, a, b;

    private Incrementer(int a, int b, int step) {
        this.step = step;
        this.a = a;
        this.b = b;
        if (step > 0)
            val = a;
        else
            val = b;
    }

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {

            @Override
            public boolean hasNext() {
                if (step < 0 && val > a)
                    return true;
                else if (step > 0 && val < b)
                    return true;
                return false;
            }

            @Override
            public Integer next() {
                return val += step;
            }

            @Override
            public void remove() {
            }
        };
    }

    public static Incrementer in(int a, int b) {
        ///tu zmieniamy tresc dla ostatniego przypadku

        if (a < b)
            return new Incrementer(a, b, 1);
        else
            return new Incrementer(b, a, -1);
    }

    public Incrementer by(int step) {
        this.step = step;
        if (this.step < 0 && this.a < this.b || this.step > 0 && this.a > this.b) {
            int tmp = this.a;
            this.a = this.b;
            this.b = tmp;
        }
        return this;
    }

}

和測試代碼:

package in;
import static in.Incrementer.*;

public class Test {

  public static void main(String[] args) {

    for(int k : in(1, 10)) System.out.print(k + " ");
    System.out.println();


    for(int k : in(1, 10).by(2)) System.out.print(k + " ");
    System.out.println();

    for(int k : in(10, 1)) System.out.print(k + " ");
    System.out.println();

    for(int k : in(1, 10).by(-1)) System.out.print(k + " ");
    System.out.println();

    Incrementer inc;
    for (int i : inc = in(1,10) ) {
      if (i == 4) inc.by(2);
      System.out.print(i + " ");
    }
    System.out.println();
    for (int i : inc = in(1,10) ) {
      if (i == 8) inc.by(-2);
      System.out.print(i + " ");
    }
    System.out.println();
    for(int k : inc = in(10, 1)) {
      if (k == 5) inc.by(1);
      System.out.print(k + " ");
    }

  }


}

我不知道我在哪里犯了錯誤。

錯誤是您沒有初始化val ,所以它將以0 (默認值)開始。

在第二個示例中,您將return val += step; ,其中val = 0step = 2 ,因此它將從2開始並從那里繼續。

在第三個示例中, a = 10b = 1step = -1val = 0 ,因此您將不會輸入

if (step < 0 && val > a)

因為val < a ,您將不會輸入

else if (step > 0 && val < b)

因為step < 0

編輯:

在編輯過的帖子中,您應該修改next()方法以返回val ,並僅在以下情況下增加它:

@Override
public Integer next() {
    int ret = val;
    val += step;
    return val;
}

您還應該修改hasNext()的條件:

@Override
public boolean hasNext() {
    if (step < 0 && val >= a)
        return true;
    else if (step > 0 && val <= b)
        return true;
    return false;
}

為了使您的第四項測試工作,如果需要,您將必須更改by()方法以反轉ab

public Incrementer by(int step) {
    if ((this.step<0)!=(step<0) && this.val==this.a)
        this.val = this.b;
    else if ((this.step<0)!=(step<0) && this.val==this.b) 
        this.val = this.a;
    else if (this.val!=this.a && this.val!=this.b) {
        this.val -= this.step;
        this.val += step;
    }
    this.step = step;

    return this;
}

您還可以測試反情況:

for(int k : in(10, 1).by(1)) System.out.print(k + " ");

這是完整的代碼:

public class Incrementer implements Iterable<Integer> {
    int val, step, a, b;

    private Incrementer(int a, int b, int step) {
        this.step = step;
        this.a = a;
        this.b = b;
        if (step > 0)
            val = a;
        else
            val = b;
    }

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {

            @Override
            public boolean hasNext() {
                if (step < 0 && val >= a)
                    return true;
                else if (step > 0 && val <= b)
                    return true;
                return false;
            }

            @Override
            public Integer next() {
                int ret = val;
                val += step;
                return ret;
            }

            @Override
            public void remove() {
            }
        };
    }

    public static Incrementer in(int a, int b) {
        ///tu zmieniamy tresc dla ostatniego przypadku

        if (a < b)
            return new Incrementer(a, b, 1);
        else
            return new Incrementer(b, a, -1);
    }

    public Incrementer by(int step) {
        if ((this.step<0)!=(step<0) && this.val==this.a)
            this.val = this.b;
        else if ((this.step<0)!=(step<0) && this.val==this.b)
            this.val = this.a;
        else if (this.val!=this.a && this.val!=this.b) {
            this.val -= this.step;
            this.val += step;
        }
        this.step = step;

        return this;
    }

}

首先,您犯了一個根本性的錯誤: Iterable應該可以發出無限多個Iterator ,但是您只能發出一個。

每個Iterator應該具有足夠的內部狀態,以便能夠迭代您的值集。

要同時解決此問題和其他問題,請在iterator()中將代碼更改為此:

@Override
public Iterator<Integer> iterator() {
    return new Iterator<Integer>() {
        int val = a; // <-- HERE

並將您的.next()更改為:

public Integer next()
{
    int ret = val;
    val += step;
    return ret;
}

並刪除其他val

(另外,我建議您將a重命名為start ,將b重命名為end


最后說明:為了完全遵守Iterator的約定,您的.remove()應該這樣做:

public void remove()
{
    throw new UnsupportedOperationException();
}

不,您無需聲明該方法引發此異常,因為它是未經檢查的異常。 請參閱javadoc以獲取RuntimeException

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM