/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package pt.isel.mpd14.iters;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.function.Function;
import java.util.function.Predicate;
/**
*
* @author Miguel Gamboa at CCISEL
*/
class IterableQueryable<T> implements Queryable<T> {
final Iterable<T> src;
public IterableQueryable(Iterable<T> src) {
this.src = src;
}
@Override
public Queryable<T> filter(Predicate<T> p) {
return new IterableQueryable<>(new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
private final Iterator<T> srcIter = src.iterator();
private T nextElem = null;
private boolean valueReady = false;
@Override
public boolean hasNext() {
if (valueReady) {
return true;
}
while (srcIter.hasNext()) {
T elem = srcIter.next();
if (p.test(elem)) {
nextElem = elem;
valueReady = true;
return true;
}
}
return false;
}
@Override
public T next() {
if (!valueReady && !hasNext())
throw new NoSuchElementException();
else {
valueReady = false;
return nextElem;
}
}
};
}
});
}
@Override
public <R> Queryable<R> map(Function<T, R> mapper) {
return new IterableQueryable<>(new Iterable<R>() {
@Override
public Iterator<R> iterator() {
return new Iterator<R>(){
private final Iterator<T> srcIter = src.iterator();
@Override
public boolean hasNext() {
return srcIter.hasNext();
}
@Override
public R next() {
return mapper.apply(srcIter.next());
}
};
}
});
}
@Override
public Queryable<T> skip(int n) {
return new IterableQueryable<>(new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
private final Iterator<T> srcIter = src.iterator();
private int skips = n;
@Override
public boolean hasNext() {
while (skips > 0 && srcIter.hasNext()) {
srcIter.next();
skips--;
}
return srcIter.hasNext();
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return srcIter.next();
}
};
}
});
}
@Override
public Iterator<T> iterator() {
return src.iterator();
}
}