我必须以这种方式迭代一个arraylist。
ArrayList<Integer> li = new ArrayList<Integer>();
li.add(20);
li.add(30);
li.add(40);
li.add(50);
li.add(70);
for (int i = 0; i < li.size() - 1; i++)
System.out.println(li.get(i) + " " + li.get(i + 1));
20 30
30 40
40 50
50 70
如何使用迭代器做同样的事情?
答案 0 :(得分:6)
使用两个迭代器。我测试了这个,它对我有用。
Iterator<Integer> first = li.listIterator();
// Will raise IndexOutOfBoundsException if list is empty.
Iterator<Integer> second = li.listIterator(1);
while (second.hasNext()) {
System.out.println(first.next() + " " + second.next());
}
修改:无需内部if
。傻我。
说明:listIterator(index)
方法返回一个迭代器,该迭代器从列表中的指定位置开始,其中listIterator()
返回从零位开始的迭代器。
first
迭代器因此从0
开始,second
从1
开始。那么这只是在两者上打印next()
的问题。无论列表中的元素数量是奇数还是偶数,这都将起作用。
修改2
我今天的逻辑很弱。感谢@barjak指出有关空列表和不必要的first.hasNext()
的案例。
答案 1 :(得分:1)
这有点复杂:
Iterator<Integer> iter = li.iterator();
if (iter.hasNext()) {
for (int y = iter.next(), x; iter.hasNext(); y = x) {
x = iter.next();
System.out.println(y + " " + x);
}
}
或:
if (iter.hasNext()) {
for (int x = iter.next(); iter.hasNext();) {
System.out.println(x + " " + (x = iter.next()));
}
}
答案 2 :(得分:1)
略微修改Sagar V的解决方案,使其工作。一个迭代器足以实现这一目标。
Iterator iter = li.iterator();
Integer int1 = null;
while (iter.hasNext()) {
if (int1 == null) {
int1 = (Integer) iter.next();
}
System.out.print(int1 + " ");
if (iter.hasNext()) {
Integer int2 = (Integer) iter.next();
System.out.println(int2);
int1 = int2;
} else {
break;
}
}
}
答案 3 :(得分:0)
有许多解决方案,根据您的需要而定。
迭代列表子集的经典方法是创建原始列表的较窄视图,并迭代整个视图。 subList
方法用于创建此类视图。
List<Integer> l = // initialization code
int limitIndex = Math.max(l.size()-1, 0); // needed for empty list
for (int v : l.subList(0, limitIndex)) {
// your code
}
请注意,我使用了'foreach'循环,这是一种使用迭代器的便捷方法。这完全等同于此代码:
Iterator<Integer> it = l.subList(0, limitIndex).iterator();
while(it.hasNext()) {
int v = it.next();
// your code
}
另请注意,subList
方法不会创建新列表:它只会在原始列表中创建“视图”。不会复制原始列表的内容,并且可以从subList
创建的列表中看到对原始列表所做的所有更改。
如果你需要的是一个总是从0迭代到n-1的迭代器,你可以定义一个适合特定需求的新Iterable
。
public class NoLastIterable<T> implements Iterable<T> {
private final List<T> backend;
public NoLastIterable(List<T> backend) {
this.backend = backend;
}
public Iterator<T> iterator() {
return new Iterator<T>() {
private int nextIndex;
public boolean hasNext() {
return nextIndex < backend.size() -1;
}
public T next() {
return backend.get(nextIndex++);
}
public void remove() {
throw new UnsupportedOperationException("not implemented");
}
};
}
}
这个类的用法如下:
for (int v : new NoLastIterable<Integer>(l)) {
// your code
}
您甚至可以创建List
的自定义视图,就像subList
一样,但具有更大的灵活性。
public class NoLastList<T> extends AbstractList<T> {
private final List<T> backend;
public NoLastList(List<T> backend) {
this.backend = backend;
}
@Override
public T get(int index) {
if (index >= size()) {
throw new IndexOutOfBoundsException();
}
return backend.get(index);
}
@Override
public int size() {
return Math.max(0, backend.size()-1);
}
}
与其他解决方案的用法相同:
for (int v : new NoLastList<Integer>(l)) {
// your code
}
在以下情况下可以看到此解决方案的好处:
NoLastList
实例(作为原始列表的视图)在这种情况下,迭代NoLastList
将考虑最近添加的元素。 NoLastList
始终表示从0到n-1的元素视图,即使n(大小)发生变化也是如此。