Java에서 다중 반복기에 참여하는 방법을 아는 사람이 있습니까? 발견 된 솔루션은 먼저 하나의 반복자를 통해 반복하고, 다음 반복으로 이동합니다. 그러나, 내가 원하는 것은 next()가 호출되면, 첫 번째 요소를 첫 번째 이터레이터에서 반환합니다. 다음에 next()가 호출되면 두 번째 이터레이터에서 첫 번째 요소를 반환하는 식으로 계속됩니다.자바의 다중 반복기에 참여하십시오.
감사
Java에서 다중 반복기에 참여하는 방법을 아는 사람이 있습니까? 발견 된 솔루션은 먼저 하나의 반복자를 통해 반복하고, 다음 반복으로 이동합니다. 그러나, 내가 원하는 것은 next()가 호출되면, 첫 번째 요소를 첫 번째 이터레이터에서 반환합니다. 다음에 next()가 호출되면 두 번째 이터레이터에서 첫 번째 요소를 반환하는 식으로 계속됩니다.자바의 다중 반복기에 참여하십시오.
감사
편의를 위해 Guava'sAbstractIterator
사용 :
final List<Iterator<E>> theIterators;
return new AbstractIterator<E>() {
private Queue<Iterator<E>> queue = new LinkedList<Iterator<E>>(theIterators);
@Override protected E computeNext() {
while(!queue.isEmpty()) {
Iterator<E> topIter = queue.poll();
if(topIter.hasNext()) {
E result = topIter.next();
queue.offer(topIter);
return result;
}
}
return endOfData();
}
};
이 당신에게 원하는 "인터리브"순서를 줄 것이다,이 컬렉션은 서로 다른 크기를 갖는 처리 할만큼 똑똑하고, 아주 소형입니다. (Java 6 이상을 사용 중이라고 가정 할 때 대신 ArrayDeque
을 사용하여 속도를 향상시킬 수 있습니다.)
다른 타사 라이브러리를 정말로 용인 할 수 없다면 더 많은 그래서 같은 몇 가지 추가 작업과 같은 일이 : 참고로
return new Iterator<E>() {
private Queue<Iterator<E>> queue = new LinkedList<Iterator<E>>(theIterators);
public boolean hasNext() {
// If this returns true, the head of the queue will have a next element
while(!queue.isEmpty()) {
if(queue.peek().hasNext()) {
return true;
}
queue.poll();
}
return false;
}
public E next() {
if(!hasNext()) throw new NoSuchElementException();
Iterator<E> iter = queue.poll();
E result = iter.next();
queue.offer(iter);
return result;
}
public void remove() { throw new UnsupportedOperationException(); }
};
은 "iter1의 모든 iter2의 모든 등"문제는 또한 Iterators.concat(Iterator<Iterator>)
하고 오버로드를 사용하여 얻을 수 있습니다.
가장 간단한 방법은
for(Type1 t1: collection1)
for(Type2 t2: collection2)
당신이 원하는 그것이이 컬렉션 간의 조인을 수행하는 경우가 작동합니다.
두 개의 컬렉션을 반복하려면 두 개의 루프를 사용하거나 두 가지 컬렉션을 모두 만듭니다.
for(Type t1: collection1)
process(t1);
for(Type t2: collection2)
process(t2);
반복기를 인터리브하려는 경우 배열을 사용할 수 있습니다.
Iterator[] iters = { iter1, iter2, ... };
boolean finished;
do {
finished = true;
for(Iterator it: iters) {
if (it.hasNext()) {
Object obj = it.next();
// process
finished = false;
}
}
} while(!finished);
인터리브를 사용하는 것 같습니다.. 이런 식으로 뭔가 - 완전히 검증되지 않은 ...
public class InterleavingIterable<E> implements Iterable<E> {
private final Iterable<? extends E> first;
private final Iterable<? extends E> second;
public InterleavingIterable(Iterable<? extends E> first,
Iterable<? extends E> second) {
this.first = first;
this.second = second;
}
public Iterator<E> iterator() {
return new InterleavingIterator<E>(first.iterator(),
second.iterator());
}
private static class InterleavingIterator<E> implements Iterator<E> {
private Iterator<? extends E> next;
private Iterator<? extends E> current;
private InterleavingIterator(Iterator<? extends E> first,
Iterator<? extends E> second) {
next = first;
current = second;
}
public boolean hasNext() {
return next.hasNext() || (current != null && current.hasNext());
}
public E next() throws NoSuchElementException {
if (next.hasNext()) {
E ret = next.next();
if (current != null) {
Iterator<? extends E> tmp = current;
current = next;
next = tmp;
}
return ret;
} else {
// Nothing left in next... check "current"
if (current == null || !current.hasNext()) {
throw new NoSuchElementException();
}
next = current;
current = null;
return current.next();
}
}
public void remove() {
throw new UnsupportedOperationException();
}
}
}
편집 : 아차, 질문을 잘못 해석. 당신은 실제로 대신 복합 반복자의, 인터리빙 반복자를 필요
class InterleavingIterator<T> implements Iterator<T> {
private final Iterator<T> internalIter;
public InterleavingIterator(final Iterator<T>... iterators) {
final LinkedList<Iterator<T>> iteratorQueue = new LinkedList<Iterator<T>>();
for (final Iterator<T> loopIter : iterators) {
if (loopIter.hasNext()) {
iteratorQueue.push(loopIter);
}
}
// create the interleaving
final LinkedList<T> internalList = new LinkedList<T>();
while (!iteratorQueue.isEmpty()) {
final Iterator<T> loopIter = iteratorQueue.pop();
internalList.add(loopIter.next());
if (loopIter.hasNext()) {
iteratorQueue.push(loopIter);
}
}
internalIter = internalList.iterator();
}
public boolean hasNext() {
return internalIter.hasNext();
}
public T next() {
return internalIter.next();
}
public void remove() {
throw new UnsupportedOperationException("remove() unsupported");
}
}
최종 편집. 동일 수집 또는 다른 컬렉션에서 각 반복자에
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
public class CompoundIterator<T> implements Iterator<T> {
private final LinkedList<Iterator<T>> iteratorQueue;
private Iterator<T> current;
public CompoundIterator(final Iterator<T>... iterators) {
this.iteratorQueue = new LinkedList<Iterator<T>>();
for (final Iterator<T> iterator : iterators) {
iteratorQueue.push(iterator);
}
current = Collections.<T>emptyList().iterator();
}
public boolean hasNext() {
final boolean curHasNext = current.hasNext();
if (!curHasNext && !iteratorQueue.isEmpty()) {
current = iteratorQueue.pop();
return current.hasNext();
} else {
return curHasNext;
}
}
public T next() {
if (current.hasNext()) {
return current.next();
}
if (!iteratorQueue.isEmpty()) {
current = iteratorQueue.pop();
}
return current.next();
}
public void remove() {
throw new UnsupportedOperationException("remove() unsupported");
}
}
여러 반복자 :
당신은 복합 반복자를 사용하는 같은 뭔가가 필요? – kosa
Yikes : http://stackoverflow.com/questions/3610261/is-it-possible-to-merge-iterators-in-java –
@RobertPeters 그래, 속는 사람 같아. flyingfromchina, 당신이 질문을 명확히하고 싶은 것의 예를 게시 할 수 있습니까? – daveslab