JBIterable: stateful filters/transforms/generators

JBIterator: ability to introspect operations
This commit is contained in:
Gregory.Shrago
2015-08-10 16:20:23 +03:00
parent e9501a133a
commit 04825889a9
3 changed files with 117 additions and 34 deletions
@@ -68,6 +68,16 @@ public class TreeTraverserTest extends TestCase {
}
};
private static final Function<Integer, Integer> FIBONACCI2 = new JBIterable.StatefulTransform<Integer, Integer>() {
int k0;
@Override
public Integer fun(Integer k) {
int t = k0;
k0 = k;
return t + k;
}
};
@NotNull
private static Condition<Integer> LESS_THAN(final int max) {
return new Condition<Integer>() {
@@ -90,6 +100,13 @@ public class TreeTraverserTest extends TestCase {
// JBIterable ----------------------------------------------
public void testAppend() {
JBIterable<Integer> it = JBIterable.of(1, 2, 3).append(JBIterable.of(4, 5, 6)).append(7);
assertEquals(7, it.size());
assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7), it.toList());
assertTrue(it.contains(5));
}
public void testGenerateRepeat() {
JBIterable<Integer> it = JBIterable.generate(1, INCREMENT).take(3).repeat(3);
assertEquals(9, it.size());
@@ -137,6 +154,26 @@ public class TreeTraverserTest extends TestCase {
}
}
public void testStatefulFilter() {
JBIterable<Integer> it = JBIterable.generate(1, INCREMENT).take(5).filter(new JBIterable.StatefulFilter<Integer>() {
int prev;
@Override
public boolean value(Integer integer) {
boolean b = integer > prev;
if (b) prev = integer;
return b;
}
});
assertEquals(Arrays.asList(1, 2, 3, 4, 5), it.toList());
assertEquals(Arrays.asList(1, 2, 3, 4, 5), it.toList());
}
public void testStatefulGenerator() {
JBIterable<Integer> it = JBIterable.generate(1, FIBONACCI2).take(8);
assertEquals(Arrays.asList(1, 1, 2, 3, 5, 8, 13, 21), it.toList());
assertEquals(Arrays.asList(1, 1, 2, 3, 5, 8, 13, 21), it.toList());
}
// TreeTraversal ----------------------------------------------
@NotNull
@@ -108,6 +108,7 @@ public abstract class JBIterable<E> implements Iterable<E> {
return new JBIterable<E>() {
@Override
public Iterator<E> iterator() {
final Function<? super E, ? extends E> fun = Stateful.copy(generator);
return new JBIterator<E>() {
E cur = first;
@@ -115,7 +116,7 @@ public abstract class JBIterable<E> implements Iterable<E> {
public E nextImpl() {
E result = cur;
if (result == null) return stop();
cur = generator.fun(cur);
cur = fun.fun(cur);
return result;
}
};
@@ -228,14 +229,14 @@ public abstract class JBIterable<E> implements Iterable<E> {
* {@code Iterator} supports it.
*/
public final JBIterable<E> append(@Nullable Iterable<? extends E> other) {
return other == null ? this : this == EMPTY ? from(other) : from(ContainerUtil.concat(myIterable, other));
return other == null ? this : this == EMPTY ? from(other) : of(myIterable, other).flatten(Functions.<Iterable<?>, Iterable<E>>identity());
}
public final <T> JBIterable<E> append(@Nullable Iterable<T> other, @NotNull Function<? super T, ? extends Iterable<? extends E>> fun) {
return other == null ? this : this == EMPTY ? from(other).flatten(fun) : append(from(other).flatten(fun));
}
public final JBIterable<E> repeat(final int count) {
public final JBIterable<E> repeat(int count) {
Function<JBIterable<E>, JBIterable<E>> fun = Functions.identity();
return generate(this, fun).take(count).flatten(fun);
}
@@ -259,7 +260,7 @@ public abstract class JBIterable<E> implements Iterable<E> {
return intercept(new Function<Iterator<E>, Iterator<E>>() {
@Override
public Iterator<E> fun(Iterator<E> iterator) {
return JBIterator.from(iterator).filter(condition);
return JBIterator.from(iterator).filter(Stateful.copy(condition));
}
});
}
@@ -288,7 +289,7 @@ public abstract class JBIterable<E> implements Iterable<E> {
return intercept(new Function<Iterator<E>, Iterator<E>>() {
@Override
public Iterator<E> fun(Iterator<E> iterator) {
return JBIterator.from(iterator).takeWhile(condition);
return JBIterator.from(iterator).takeWhile(Stateful.copy(condition));
}
});
}
@@ -308,7 +309,7 @@ public abstract class JBIterable<E> implements Iterable<E> {
return intercept(new Function<Iterator<E>, Iterator<E>>() {
@Override
public Iterator<E> fun(Iterator<E> iterator) {
return JBIterator.from(iterator).skipWhile(condition);
return JBIterator.from(iterator).skipWhile(Stateful.copy(condition));
}
});
}
@@ -326,7 +327,7 @@ public abstract class JBIterable<E> implements Iterable<E> {
return intercept(new Function<Iterator<E>, Iterator<T>>() {
@Override
public Iterator<T> fun(Iterator<E> iterator) {
return JBIterator.from(iterator).transform(function);
return JBIterator.from(iterator).transform(Stateful.copy(function));
}
});
}
@@ -344,13 +345,14 @@ public abstract class JBIterable<E> implements Iterable<E> {
return intercept(new Function<Iterator<E>, Iterator<T>>() {
@Override
public Iterator<T> fun(final Iterator<E> iterator) {
final Function<? super E, ? extends Iterable<? extends T>> fun = Stateful.copy(function);
return new JBIterator<T>() {
Iterator<? extends T> cur;
@Override
public T nextImpl() {
while ((cur == null || !cur.hasNext()) && iterator.hasNext()) {
cur = function.fun(iterator.next()).iterator();
cur = fun.fun(iterator.next()).iterator();
}
if (cur == null || !cur.hasNext()) return stop();
return cur.next();
@@ -456,4 +458,33 @@ public abstract class JBIterable<E> implements Iterable<E> {
}
return collection;
}
@SuppressWarnings("unchecked")
public abstract static class Stateful<Self extends Stateful> implements Cloneable {
@NotNull
static <T> T copy(@NotNull T o) {
if (!(o instanceof Stateful)) {
return o;
}
return (T)((Stateful)o).clone();
}
public Self clone() {
try {
return (Self)super.clone();
}
catch (CloneNotSupportedException e) {
throw new AssertionError(e);
}
}
}
public abstract static class StatefulFilter<T> extends Stateful<StatefulFilter> implements Condition<T> {
}
public abstract static class StatefulTransform<S, T> extends Stateful<StatefulTransform> implements Function<S, T> {
}
}
@@ -68,7 +68,7 @@ public abstract class JBIterator<E> implements Iterator<E> {
}
private Object cur = INIT;
private final Op firstOp = new Op();
private final Op firstOp = new Op(null);
private Op lastOp = firstOp;
protected abstract E nextImpl();
@@ -125,31 +125,21 @@ public abstract class JBIterator<E> implements Iterator<E> {
}
@NotNull
public final <T> JBIterator<T> transform(@NotNull final Function<? super E, T> function) {
return addOp(new Op() {
public final <T> JBIterator<T> transform(@NotNull Function<? super E, T> function) {
return addOp(new Op<Function<? super E, T>>(function) {
@Override
public Object apply(Object o) {
return function.fun((E)o);
}
@Override
public String toString() {
return toShortString(function);
return impl.fun((E)o);
}
});
}
@NotNull
public final JBIterator<E> filter(@NotNull final Condition<? super E> condition) {
return addOp(new Op() {
public final JBIterator<E> filter(@NotNull Condition<? super E> condition) {
return addOp(new Op<Condition<? super E>>(condition) {
@Override
public Object apply(Object o) {
return condition.value((E)o) ? o : SKIP;
}
@Override
public String toString() {
return toShortString(condition);
return impl.value((E)o) ? o : SKIP;
}
});
}
@@ -160,16 +150,16 @@ public abstract class JBIterator<E> implements Iterator<E> {
}
@NotNull
public final JBIterator<E> takeWhile(@NotNull final Condition<? super E> condition) {
return addOp(new Op() {
public final JBIterator<E> takeWhile(@NotNull Condition<? super E> condition) {
return addOp(new Op<Condition<? super E>>(condition) {
@Override
public Object apply(Object o) {
return condition.value((E)o) ? o : stop();
return impl.value((E)o) ? o : stop();
}
@Override
public String toString() {
return "while:" + toShortString(condition);
return "takeWhile:" + super.toString();
}
});
}
@@ -181,7 +171,7 @@ public abstract class JBIterator<E> implements Iterator<E> {
@NotNull
public final JBIterator<E> skipWhile(@NotNull final Condition<? super E> condition) {
return addOp(new Op() {
return addOp(new Op<Condition<? super E>>(condition) {
boolean active = true;
@@ -194,7 +184,7 @@ public abstract class JBIterator<E> implements Iterator<E> {
@Override
public String toString() {
return "skip:" + toShortString(condition);
return "skipWhile:" + super.toString();
}
});
}
@@ -218,13 +208,28 @@ public abstract class JBIterator<E> implements Iterator<E> {
@Override
public String toString() {
JBIterable<Op> ops = JBIterable.generate(firstOp.nextOp, new Function<Op, Op>() {
JBIterable<Op> ops = operationsImpl();
return "{cur=" + cur + "; ops[" + ops.size() + "]=" + ops + "}";
}
@NotNull
public JBIterable<Object> operations() {
return operationsImpl().transform(new Function<Op, Object>() {
@Override
public Object fun(Op op) {
return op.impl;
}
});
}
@NotNull
private JBIterable<Op> operationsImpl() {
return JBIterable.generate(firstOp.nextOp, new Function<Op, Op>() {
@Override
public Op fun(Op op) {
return op.nextOp;
}
});
return "{cur=" + cur + "; ops[" + ops.size() + "]=" + ops + "}";
}
private static String toShortString(@NotNull Object o) {
@@ -239,12 +244,22 @@ public abstract class JBIterator<E> implements Iterator<E> {
}
};
private static class Op {
private static class Op<T> {
final T impl;
Op nextOp;
public Op(T impl) {
this.impl = impl;
}
Object apply(Object o) {
throw new UnsupportedOperationException();
}
@Override
public String toString() {
return impl == null ? "" : toShortString(impl);
}
}
private static class CountDown<A> implements Condition<A> {