org.canova.api.berkeley.Iterators Maven / Gradle / Ivy
/*
*
* *
* * * Copyright 2015 Skymind,Inc.
* * *
* * * Licensed under the Apache License, Version 2.0 (the "License");
* * * you may not use this file except in compliance with the License.
* * * You may obtain a copy of the License at
* * *
* * * http://www.apache.org/licenses/LICENSE-2.0
* * *
* * * Unless required by applicable law or agreed to in writing, software
* * * distributed under the License is distributed on an "AS IS" BASIS,
* * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * * See the License for the specific language governing permissions and
* * * limitations under the License.
* *
*
*/
package org.canova.api.berkeley;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
public class Iterators {
public static void fillList(Iterator extends T> it, List lst) {
while (it.hasNext()) {
lst.add(it.next());
}
}
public static List fillList(Iterator extends T> it) {
List lst = new ArrayList<>();
fillList(it, lst);
return lst;
}
/**
* Wraps a base iterator with a transformation function.
*/
public static abstract class Transform implements Iterator {
private Iterator base;
public Transform(Iterator base) {
this.base = base;
}
public boolean hasNext() {
return base.hasNext();
}
public T next() {
return transform(base.next());
}
protected abstract T transform(S next);
public void remove() {
base.remove();
}
}
private Iterators() {
}
/**
* Wraps an iterator as an iterable
*
* @param
* @param it
* @return
*/
public static Iterable newIterable(final Iterator it) {
return new Iterable() {
public Iterator iterator() {
return it;
}
};
}
/**
* Wraps an iterator as an iterable
*
* @param
* @param it
* @return
*/
public static Iterable able(final Iterator it) {
return new Iterable() {
boolean used = false;
public Iterator iterator() {
if (used) throw new RuntimeException("One use iterable");
used = true;
return it;
}
};
}
/**
* Executes calls to next() in a different thread
*
* @param
* @param base
* @return
*/
public static Iterator thread(final Iterator base) {
return new Iterator() {
ArrayBlockingQueue els = new ArrayBlockingQueue(2);
private boolean finishedLoading = false;
private boolean running = false;
Thread thread = new Thread(new Runnable() {
public void run() {
while (base.hasNext()) {
try {
els.put(base.next());
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
finishedLoading = true;
}
});
public boolean hasNext() {
return !(finishedLoading && els.isEmpty());
}
public T next() {
if (!running) thread.start();
running = true;
try {
return els.take();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public static Iterator> zip(final Iterator s, final Iterator t) {
return new Iterator>() {
public boolean hasNext() {
return s.hasNext() && t.hasNext();
}
public Pair next() {
return Pair.newPair(s.next(), t.next());
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
/**
* Provides a max number of elements for an underlying base iterator.
*/
public static Iterator maxLengthIterator(final Iterator base, final int max) {
return new Iterator() {
int count = 0;
public boolean hasNext() {
return base.hasNext() && count < max;
}
public T next() {
if (!hasNext()) throw new NoSuchElementException("No more elements");
count++;
return base.next();
}
public void remove() {
throw new UnsupportedOperationException();
// TODO Maybe this should behave in a more friendly manner
}
};
}
/**
* Wraps a two-level iteration scenario in an iterator. Each key of the keys
* iterator returns an iterator (via the factory) over T's.
*
* The IteratorIterator loops through the iterator associated with each key
* until all the keys are used up.
*/
public static class IteratorIterator implements Iterator {
Iterator current = null;
Iterator keys;
Factory> iterFactory;
public IteratorIterator(Iterator keys, Factory> iterFactory) {
this.keys = keys;
this.iterFactory = iterFactory;
current = getNextIterator();
}
private Iterator getNextIterator() {
Iterator next = null;
while (next == null) {
if (!keys.hasNext()) break;
next = iterFactory.newInstance(keys.next());
if (!next.hasNext()) next = null;
}
return next;
}
public boolean hasNext() {
return current != null;
}
public T next() {
T next = current.next();
if (!current.hasNext()) current = getNextIterator();
return next;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
/**
* Creates an iterator that only returns items of a base iterator that pass
* a filter.
*
* Null items cannot be returned from the base iterator.
*/
public static class FilteredIterator implements Iterator {
Filter filter;
T next;
private Iterator base;
public FilteredIterator(Filter filter, Iterator base) {
super();
this.filter = filter;
this.base = base;
loadNext();
}
public FilteredIterator(Filter filter, Iterable items) {
this(filter, items.iterator());
}
private void loadNext() {
next = null;
while (next == null && base.hasNext()) {
next = base.next();
if (!filter.accept(next)) next = null;
}
}
public boolean hasNext() {
return next != null;
}
public T next() {
T old = next;
loadNext();
return old;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
public static class TransformingIterator implements Iterator {
private MyMethod transformer;
private Iterator inputIterator;
public TransformingIterator(Iterator inputIterator, MyMethod transformer) {
this.inputIterator = inputIterator;
this.transformer = transformer;
}
public boolean hasNext() {
return inputIterator.hasNext();
}
public O next() {
return transformer.call(inputIterator.next());
}
public void remove() {
inputIterator.remove();
}
}
public static Iterator filter(Iterator iterator, Filter filter) {
return new FilteredIterator(filter, iterator);
}
public static Iterator concat(Iterable> args) {
Factory> factory = new Factory>() {
public Iterator newInstance(Object... args) {
return (Iterator) args[0];
}
};
return new IteratorIterator(Arrays.asList(args).iterator(), factory);
}
public static Iterator concat(Iterator extends T>... args) {
Factory> factory = new Factory>() {
public Iterator newInstance(Object... args) {
return (Iterator) args[0];
}
};
return new IteratorIterator(Arrays.asList(args).iterator(), factory);
}
public static Iterator oneItemIterator(final U item) {
return new Iterator() {
boolean unused = true;
public boolean hasNext() {
return unused;
}
public U next() {
unused = false;
return item;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public static Iterator emptyIterator() {
return new Iterator() {
public boolean hasNext() {
return false;
}
public Object next() {
throw new NoSuchElementException();
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public static Iterable concat(Iterable a, Iterable b) {
return able(concat(a.iterator(), b.iterator()));
}
public static List nextList(List> iterators) {
List items = new ArrayList(iterators.size());
for (Iterator iter : iterators) {
items.add(iter.next());
}
return items;
}
public static Iterator