Advertisement
Guest User

Java 8 optionalMap Example

a guest
Nov 2nd, 2012
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. public interface OptionalMapper<T, R> {
  2.     Optional<R> optionalMap(T t);
  3. }
  4.  
  5. public class OptionalMapOp<T, R> implements IntermediateOp<T, R> {
  6.     public final OptionalMapper<? super T, ? extends R> mapper;
  7.  
  8.     public OptionalMapOp(OptionalMapper<? super T, ? extends R> mapper) {
  9.         this.mapper = Objects.requireNonNull(mapper);
  10.     }
  11.  
  12.     @Override
  13.     public int getOpFlags() {
  14.         return StreamOpFlags.NOT_SORTED | StreamOpFlags.NOT_DISTINCT;
  15.     }
  16.  
  17.     @Override
  18.     public Iterator<R> wrapIterator(int flags, final Iterator<T> source) {
  19.         return iterator(source, mapper);
  20.     }
  21.  
  22.     @Override
  23.     public Sink<T> wrapSink(int flags, Sink sink) {
  24.         return new Sink.ChainedValue<T>(sink) {
  25.             @Override
  26.             public void accept(T t) {
  27.                 for (R r : Optionals.toIterable(mapper.optionalMap(t))) {
  28.                     downstream.accept(r);
  29.                 }
  30.             }
  31.         };
  32.     }
  33.  
  34.     public static<T, R> Iterator<R> iterator(final Iterator<T> source, final OptionalMapper<? super T, ? extends R> mapper) {
  35.         Objects.requireNonNull(source);
  36.         Objects.requireNonNull(mapper);
  37.  
  38.         return new OptionalMapIterator(source, mapper);
  39.     }
  40.  
  41.     static class OptionalMapIterator<T, R> implements Iterator<R> {
  42.         final Iterator<T> source;
  43.         final OptionalMapper<? super T, ? extends R> mapper;
  44.  
  45.         boolean haveNext = false;
  46.         Optional<? extends R> nextValue = Optional.<R>empty();
  47.  
  48.         OptionalMapIterator(final Iterator<T> source, final OptionalMapper<? super T, ? extends R> mapper) {
  49.             this.source = source;
  50.             this.mapper = mapper;
  51.         }
  52.  
  53.         public void tryToGetNext() {
  54.             if (!haveNext) {
  55.                 while (source.hasNext()) {
  56.                     final T sourceNext = source.next();
  57.                     nextValue = mapper.optionalMap(sourceNext);
  58.  
  59.                     if (nextValue.isPresent()) {
  60.                         haveNext = true;
  61.                         return;
  62.                     }
  63.                 }
  64.             }
  65.         }
  66.  
  67.         @Override
  68.         public boolean hasNext() {
  69.             tryToGetNext();
  70.             return haveNext;
  71.         }
  72.  
  73.         @Override
  74.         public R next() {
  75.             tryToGetNext();
  76.  
  77.             if (haveNext) {
  78.                 final Optional<? extends R> result = nextValue;
  79.                 haveNext = false;
  80.                 nextValue = Optional.<R>empty();
  81.                 return result.get();
  82.             } else {
  83.                 throw new NoSuchElementException();
  84.             }
  85.         }
  86.     }
  87. }
  88.  
  89. public class MoreStreams {
  90.     // This is a quick and dirty example that works.
  91.     // The cast and the generic types would have to be fixed for a non-throwaway implementation.
  92.     public static <T, R> Stream<R> optionalMap(Stream<T> stream, OptionalMapper<? super T, R> mapper) {
  93.         final ValuePipeline vp = (ValuePipeline) stream;
  94.         final OptionalMapOp mapOp = new OptionalMapOp<>(mapper);
  95.         return chainValue(vp, mapOp);
  96.     }
  97.  
  98.     protected static <E_IN, E_OUT> Stream<E_OUT> chainValue(AbstractPipeline<E_IN, E_OUT> pipeline, IntermediateOp<E_OUT, E_OUT> op) {
  99.         return new ValuePipeline<>(pipeline, op);
  100.     }
  101. }
  102.  
  103. public class ZipCodeTest {
  104.     public static class Address {
  105.         public final Optional<String> zipOption;
  106.         public Address(Optional<String> zipOption) { this.zipOption = zipOption; }
  107.     }
  108.     public static class Person {
  109.         public final Optional<Address> addressOption;
  110.         public Person(Optional<Address> addressOption) { this.addressOption = addressOption; }
  111.     }
  112.  
  113.     public static void main(String[] args) {
  114.         List<Person> people = new ArrayList<Person>();
  115.         people.add(new Person(Optional.<Address>empty()));
  116.         people.add(new Person(new Optional(new Address(Optional.<String>empty()))));
  117.         people.add(new Person(new Optional(new Address(new Optional("12345")))));
  118.         people.add(new Person(new Optional(new Address(Optional.<String>empty()))));
  119.         people.add(new Person(new Optional(new Address(new Optional("45678")))));
  120.         people.add(new Person(new Optional(new Address(new Optional("98765")))));
  121.         people.add(new Person(Optional.<Address>empty()));
  122.  
  123.         Stream<Person> s = people.stream();
  124.         ValuePipeline vp = (ValuePipeline) s;
  125.  
  126.         // --------------------------------------------------------
  127.         // Regular map example: JDK8 supports this...
  128.  
  129.         final List<Optional<Address>> optAddresses = new ArrayList<Optional<Address>>();
  130.         // Using static function syntax to match later examples:
  131.         MoreStreams.map(people.stream(), (p) -> p.addressOption).into(optAddresses);
  132.         // Nicer Syntax is built into JDK:
  133.         people.stream().map((p) -> p.addressOption).into(optAddresses);
  134.  
  135.         // --------------------------------------------------------
  136.         // optionalMap(flatMap) example: JDK8 purposefully omits...
  137.  
  138.         final List<Address> addresses = new ArrayList<Address>();
  139.         optionalMap(people.stream(), (p) -> p.addressOption).into(addresses);
  140.         // If JDK8 had this built-in, the nicer syntax would be :
  141.         //people.stream().optionalMap((p) -> p.addressOption).into(addresses);
  142.  
  143.         final List<String> zips = new ArrayList<String>();
  144.         optionalMap(optionalMap(people.stream(), (p) -> p.addressOption), (a) -> a.zipOption).into(zips);
  145.         // If JDK8 had this built-in, the nicer syntax would be :
  146.         //people.stream().optionalMap((p) -> p.addressOption).optionalMap((a) -> a.zipOption).into(zips);
  147.     }
  148. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement