Звучит как часть того, что вы хотите: ленивое выполнение - вам не нужно делать копию структуры в памяти перед извлечением результатов.
Я бы отнессяэто как итерация + проблема преобразования.Сначала определите итератор для вашего ввода, чтобы каждый вызов next () возвращал Callable, который будет генерировать следующее значение в вашей серии.
Этап преобразования заключается в применении параллельной или параллельной оценки этих Callables., что-то вроде этого (не проверено):
public class ConcurrentTransform
{
private final ExecutorService executor;
private final int maxBuffer;
public ConcurrentTransform(ExecutorService executor, int maxWorkBuffer) {
this.executor = executor;
this.maxBuffer = Math.max(1, maxWorkBuffer);
}
public <T> Iterator<T> apply(final Iterator<Callable<T>> input) {
// track submitted work
final BlockingQueue<Future<T>> submitted = new LinkedBlockingQueue<Future<T>>();
// submit first N tasks
for (int i=0; i<maxBuffer && input.hasNext(); i++) {
Callable<T> task = input.next();
Future<T> future = executor.submit(task);
submitted.add(future);
}
return new Iterator<T>(){
@Override
public synchronized boolean hasNext() {
return !submitted.isEmpty();
}
@Override
public T next() {
Future<T> result;
synchronized (this) {
result = submitted.poll();
if (input.hasNext()) {
submitted.add(executor.submit(input.next()));
}
}
if (result != null) {
try {
return result.get(); // blocking
} catch (Exception e) {
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else {
throw new RuntimeException(e);
}
}
} else {
throw new NoSuchElementException();
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}};
}
}
После вызова apply (...) вы переберите итоговые значения, которые под прикрытием будут выполнять объекты Callable параллельно и возвращатьрезультаты в том же порядке, в котором они были введены.Некоторые усовершенствования могут включать дополнительное время ожидания для блокирующего вызова result.get () или управление пулом потоков внутри самого преобразования.