mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
JBIterable: stateful filters/transforms/generators
JBIterator: ability to introspect operations
This commit is contained in:
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user