[英]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 = 0
且step = 2
,因此它將從2
開始並從那里繼續。
在第三個示例中, a = 10
, b = 1
, step = -1
和val = 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()
方法以反轉a
和b
:
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.