今日、HashSetのイテレータで奇妙な動作に遭遇しました。以下のコード例でidString
は、によって返されたオブジェクト参照を使用してhs.iterator
、イテレータのnext()
メソッドを呼び出します。
idString2
イテレータではviaが呼び出され、hs.iterator()
動作しなくなります。
したがって、HashSet.iterator()は、呼び出されるたびに新しいイテレータオブジェクトを返すと想定しています。しかし、なぜ私はまだhs.iterator().hasNext()
whileループで使用できるのですか?
(以下のコードは単なる例であることに注意してください:))
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import org.junit.Test;
public class DummyTest {
static final HashSet<Integer> TEST_DATA = new HashSet<Integer>(
Arrays.asList(new Integer[] {
1,2,3,4,5,6,7,8,9,10
}));
@Test
public void testRunTest() {
// Correct output: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
System.out.println(idString(TEST_DATA));
// Only 1, 1, 1, 1, ...
System.out.println(idString2(TEST_DATA));
}
static String idString(HashSet<Integer> hs) {
Iterator<Integer> it = hs.iterator();
String res = it.next() + "";
while (it.hasNext()) {
res += ", " + it.next();
System.out.println(res); // debug
}
return res;
}
static String idString2(HashSet<Integer> hs) {
Iterator<Integer> it = hs.iterator();
// Prevent an infinite loop
int i = 0;
String res = null;
res = it.next() + "";
while (hs.iterator().hasNext() && i++ <= 10) {
// if replacing hs.iterator() with 'it', it works
res = res + ", " + hs.iterator().next();
System.out.println(res); // debug
}
return res;
}
}