Lec 09 - InfiniteList and Stream
Eager List vs. Infinite List
Method Implementations
1
public T head() {
return this.head;
}public T head() {
T h = this.head.produce();
// Recursive call until head is not null
return h == null ? this.tail.produce().head() : h;
}2
public EagerList<T> tail() {
return this.tail;
}public InfiniteList<T> tail() {
T h = this.head.produce();
// Recursive call until tail is not null
return h == null ? this.tail.produce().tail() : this.tail.produce();
}3
public T get(int n) {
if (n == 0) {
return this.head();
}
return this.tail().get(n - 1);
}public T get(int n) {
if (n == 0) {
return this.head(); // be careful!
} // use the methods
return this.tail().get(n - 1); // instead of fields
}4
// generate(1, 4) -> 1 1 1 1
// generate(4, 1) -> 4
public static <T> EagerList<T> generate(T t, int size) {
if (size == 0) {
return empty();
}
return new EagerList<>(t, generate(t, size - 1));
}// generate(() -> 1) gives us 1 1 1 1 1 ...
public static <T> InfiniteList<T> generate(Producer<T> t) {
return new InfiniteList<>(t, () -> generate(t));
}5
// iterate(1, x -> x <= 10, x -> x + 1) gives us 1 2 3 4 5 6 7 8 9 10
public static <T> EagerList<T> iterate(
T init, BooleanCondition<? super T> cond, Transformer<? super T, ? extends T> op) {
if (!cond.test(init)) {
return empty();
}
return new EagerList<>(init, iterate(op.transform(init), cond, op));
}// iterate(1, x -> x + 2) gives us 1 3 5 7
public static <T> InfiniteList<T> iterate(T init, Transformer<T, T> next) {
return new InfiniteList<>(() -> init, () -> iterate(next.transform(init), next));
}6
// (1 2 3 4).map(x -> x * x) gives us (1, 4, 9, 16)
public <R> EagerList<R> map(Transformer<? super T, ? extends R> mapper) {
return new EagerList<>(mapper.transform(this.head()), this.tail.map(mapper));
}// (1 1 1 1 ...).map(x -> x * 2) gives us (2 2 2 2 ...)
public <R> InfiniteList<R> map(Transformer<? super T, ? extends R> mapper) {
return new InfiniteList<>(() -> mapper.transform(this.head()),
() -> this.tail().map(mapper));
}7
// (1 2 3 4).filter(x -> x % 2 == 0) gives us (2, 4)
public EagerList<T> filter(BooleanCondition<? super T> cond) {
if (cond.test(this.head())) {
return new EagerList<>(this.head(), this.tail().filter(cond));
}
return this.tail.filter(cond);
}public InfiniteList<T> filter(BooleanCondition<? super T> cond) {
Producer<T> newHead = () -> (cond.test(this.head()) ? this.head() : null);
return new InfiniteList<>(newHead, () -> this.tail().filter(cond));
}Tips
Under the Hood


Streams
Building a Stream
1
2
3
4
Terminal Operations
1
2
3
4
5
6
Intermediate Stream Operations
1
2
3
4
5
6
7
8
Consumed Once
Specialized Stream
1
2
3
Elegance of Stream
Last updated