Skip to content

Instantly share code, notes, and snippets.

@qzchenwl
Created August 14, 2013 03:06
Show Gist options
  • Save qzchenwl/6227684 to your computer and use it in GitHub Desktop.
Save qzchenwl/6227684 to your computer and use it in GitHub Desktop.
Stream implemented in java
package util;
import org.springframework.util.Assert;
import java.math.BigDecimal;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
Stream<Integer> evens = filter(new F1<Integer, Boolean>() {
@Override
public Boolean f(Integer a) {
return a % 2 == 0;
}
}, natures);
Stream<BigDecimal> sub = take(1000, fibs);
for(BigDecimal i : sub) {
System.out.println(i);
}
}
public static abstract class Stream<T> implements Iterable<T> {
public abstract T car();
public abstract Stream<T> cdr();
public static <T> Stream<T> cons(final T a, final Delay<Stream<T>> delayed) {
return new Stream<T>() {
@Override
public T car() {
return a;
}
@Override
public Stream<T> cdr() {
return delayed.memForce();
}
@Override
public Iterator iterator() {
return new StreamIterator<T>(this);
}
};
}
public static class StreamIterator<T> implements Iterator<T> {
private Stream<T> stream;
public StreamIterator(Stream<T> stream) {
this.stream = stream;
}
@Override
public boolean hasNext() {
return stream != null;
}
@Override
public T next() {
T e = stream.car();
stream = stream.cdr();
return e;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
}
public static abstract class Delay<T> {
private T result;
public T memForce() {
if (result == null) {
result = force();
}
return result;
}
public abstract T force();
}
public static Stream<Integer> ones = Stream.cons(1, new Delay<Stream<Integer>>() {
@Override
public Stream<Integer> force() {
return ones;
}
});
public static Stream<Integer> ints_from(final int from) {
return Stream.cons(from, new Delay<Stream<Integer>>() {
@Override
public Stream<Integer> force() {
return ints_from(from + 1);
}
});
}
public static Stream<Integer> natures = ints_from(1);
public static Stream<BigDecimal> fibgen(final BigDecimal a, final BigDecimal b) {
return Stream.cons(a, new Delay<Stream<BigDecimal>>() {
@Override
public Stream<BigDecimal> force() {
return fibgen(b, a.add(b));
}
});
}
public static Stream<BigDecimal> fibs = fibgen(BigDecimal.valueOf(0), BigDecimal.valueOf(1));
public static abstract class F1<A,B> {
public abstract B f(A a);
}
public static <T> Stream<T> filter(final F1<T, Boolean> p, final Stream<T> s) {
if (s == null) return null;
T a = s.car();
if (p.f(a)) {
return Stream.cons(a, new Delay<Stream<T>>() {
@Override
public Stream<T> force() {
return filter(p, s.cdr());
}
});
}
else {
return filter(p, s.cdr());
}
}
public static <T> Stream<T> take(final int n, final Stream<T> s) {
Assert.isTrue(n >= 0);
if (n == 0) return null;
return Stream.cons(s.car(), new Delay<Stream<T>>() {
@Override
public Stream<T> force() {
return take(n-1, s.cdr());
}
});
}
public static <A, B> Stream<B> map(final F1<A, B> f, final Stream<A> s) {
return Stream.cons(f.f(s.car()), new Delay<Stream<B>>() {
@Override
public Stream<B> force() {
return map(f, s.cdr());
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment