我编写了一个自定义迭代器类,它迭代PoSet中找到的数字集,这是我的代码:
private class IntGenerator implements Iterator {
private Iterator<Integer> i;
private Set<Integer> returnedNumbers;
public IntGenerator () {
returnedNumbers = new HashSet<Integer> ();
i = S.iterator();
}
public boolean hasNext() {
return i.hasNext();
}
public Object next() {
int n = i.next();
for (Pair p : R) {
if (isInSecondElmPair(p, n)) {
if (returnedNumbers.contains(p.getFirstElm())) {
returnedNumbers.add(n);
return n;
}else{
returnedNumbers.add(p.getFirstElm());
return p.getFirstElm();
}
}else if (isInFirstElmPair(p, n)){
returnedNumbers.add(n);
return n;
}
}
return n;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
问题是,当返回一个数字时,我应该遵守部分顺序规则,即:
1.如果(x,y)属于R
,则应在y
然而,上面的代码似乎遵循了这个顺序,但它正在创建重复项,如何修复我的代码以不允许它?
注意:在我的代码中,S是PoSet中的数字集,它是HashSet,R是成对的arraylist(对:我创建的一个类,它以2个整数作为param)来保存关系。序集。
有没有办法解决这个问题? 感谢
答案 0 :(得分:2)
您的next
方法始终调用i.next()
,并返回以下两项内容之一:
i.next()
返回的值这意味着如果您的poset包含{1,2,3,4}并使用整数的自然顺序,并且i.next()
返回4,那么您要么返回4 now (由于已经返回了1,2和3,或者你从不返回4(因为它不低于任何未来值)。
你得到重复的原因是你为i.next()
的每个值返回一个值,并且有些值永远不会被返回(参见上一段),所以自然会有一些值被返回多次赔偿。请注意,您永远不会检查i.next()
方法返回的值是否先前已由next()
方法返回,因此如果poset中的元素不大于任何其他元素,那么i.next()
时返回该元素后,您的next()
方法将自动返回该元素,即使它之前已将其返回。
我认为唯一合理的解决办法是彻底改变你的做法;我不认为你现在的方法可以很容易地发挥作用。我认为你的迭代器的构造函数需要将poset的所有元素复制到一个可接受的有序列表中,然后next()
方法将只返回该列表的下一个元素。或者,或者,因为您当前的方法已经需要在每次调用R
时迭代next()
,所以将迭代器基于{{}上的迭代器更有意义。 1}}。 (我假设R
已经使用自己进行了排序;如果不是,那么你的R
循环完全没有意义,并且基本上会返回随机选择的元素。)
如果您确实想尝试坚持自己的方法,那么您不仅需要跟踪for
方法已经返回的元素,还需要跟踪next()
返回的元素,但您的i.next()
方法不返回;你需要以后能够返回这些元素。
此外,您的next()
循环无法执行您想要的操作 - 只要找到任何小于{{1}的元素,它就会自动返回for (Pair p : R)
已经返回,即使还有其他尚未返回的n
元素。 (如果n
已经使用自己进行了排序。如果不是,那么这个循环会出现更大的问题。)