Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public interface OptionalMapper<T, R> {
- Optional<R> optionalMap(T t);
- }
- public class OptionalMapOp<T, R> implements IntermediateOp<T, R> {
- public final OptionalMapper<? super T, ? extends R> mapper;
- public OptionalMapOp(OptionalMapper<? super T, ? extends R> mapper) {
- this.mapper = Objects.requireNonNull(mapper);
- }
- @Override
- public int getOpFlags() {
- return StreamOpFlags.NOT_SORTED | StreamOpFlags.NOT_DISTINCT;
- }
- @Override
- public Iterator<R> wrapIterator(int flags, final Iterator<T> source) {
- return iterator(source, mapper);
- }
- @Override
- public Sink<T> wrapSink(int flags, Sink sink) {
- return new Sink.ChainedValue<T>(sink) {
- @Override
- public void accept(T t) {
- for (R r : Optionals.toIterable(mapper.optionalMap(t))) {
- downstream.accept(r);
- }
- }
- };
- }
- public static<T, R> Iterator<R> iterator(final Iterator<T> source, final OptionalMapper<? super T, ? extends R> mapper) {
- Objects.requireNonNull(source);
- Objects.requireNonNull(mapper);
- return new OptionalMapIterator(source, mapper);
- }
- static class OptionalMapIterator<T, R> implements Iterator<R> {
- final Iterator<T> source;
- final OptionalMapper<? super T, ? extends R> mapper;
- boolean haveNext = false;
- Optional<? extends R> nextValue = Optional.<R>empty();
- OptionalMapIterator(final Iterator<T> source, final OptionalMapper<? super T, ? extends R> mapper) {
- this.source = source;
- this.mapper = mapper;
- }
- public void tryToGetNext() {
- if (!haveNext) {
- while (source.hasNext()) {
- final T sourceNext = source.next();
- nextValue = mapper.optionalMap(sourceNext);
- if (nextValue.isPresent()) {
- haveNext = true;
- return;
- }
- }
- }
- }
- @Override
- public boolean hasNext() {
- tryToGetNext();
- return haveNext;
- }
- @Override
- public R next() {
- tryToGetNext();
- if (haveNext) {
- final Optional<? extends R> result = nextValue;
- haveNext = false;
- nextValue = Optional.<R>empty();
- return result.get();
- } else {
- throw new NoSuchElementException();
- }
- }
- }
- }
- public class MoreStreams {
- // This is a quick and dirty example that works.
- // The cast and the generic types would have to be fixed for a non-throwaway implementation.
- public static <T, R> Stream<R> optionalMap(Stream<T> stream, OptionalMapper<? super T, R> mapper) {
- final ValuePipeline vp = (ValuePipeline) stream;
- final OptionalMapOp mapOp = new OptionalMapOp<>(mapper);
- return chainValue(vp, mapOp);
- }
- protected static <E_IN, E_OUT> Stream<E_OUT> chainValue(AbstractPipeline<E_IN, E_OUT> pipeline, IntermediateOp<E_OUT, E_OUT> op) {
- return new ValuePipeline<>(pipeline, op);
- }
- }
- public class ZipCodeTest {
- public static class Address {
- public final Optional<String> zipOption;
- public Address(Optional<String> zipOption) { this.zipOption = zipOption; }
- }
- public static class Person {
- public final Optional<Address> addressOption;
- public Person(Optional<Address> addressOption) { this.addressOption = addressOption; }
- }
- public static void main(String[] args) {
- List<Person> people = new ArrayList<Person>();
- people.add(new Person(Optional.<Address>empty()));
- people.add(new Person(new Optional(new Address(Optional.<String>empty()))));
- people.add(new Person(new Optional(new Address(new Optional("12345")))));
- people.add(new Person(new Optional(new Address(Optional.<String>empty()))));
- people.add(new Person(new Optional(new Address(new Optional("45678")))));
- people.add(new Person(new Optional(new Address(new Optional("98765")))));
- people.add(new Person(Optional.<Address>empty()));
- Stream<Person> s = people.stream();
- ValuePipeline vp = (ValuePipeline) s;
- // --------------------------------------------------------
- // Regular map example: JDK8 supports this...
- final List<Optional<Address>> optAddresses = new ArrayList<Optional<Address>>();
- // Using static function syntax to match later examples:
- MoreStreams.map(people.stream(), (p) -> p.addressOption).into(optAddresses);
- // Nicer Syntax is built into JDK:
- people.stream().map((p) -> p.addressOption).into(optAddresses);
- // --------------------------------------------------------
- // optionalMap(flatMap) example: JDK8 purposefully omits...
- final List<Address> addresses = new ArrayList<Address>();
- optionalMap(people.stream(), (p) -> p.addressOption).into(addresses);
- // If JDK8 had this built-in, the nicer syntax would be :
- //people.stream().optionalMap((p) -> p.addressOption).into(addresses);
- final List<String> zips = new ArrayList<String>();
- optionalMap(optionalMap(people.stream(), (p) -> p.addressOption), (a) -> a.zipOption).into(zips);
- // If JDK8 had this built-in, the nicer syntax would be :
- //people.stream().optionalMap((p) -> p.addressOption).optionalMap((a) -> a.zipOption).into(zips);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement