SelectMany or other useful operators from Rx (Ix)

Brian Goetz brian.goetz at oracle.com
Wed Jan 9 10:30:35 PST 2013


The short answer is: if one element maps to infinitely many elements, 
you lose, otherwise everything works as expected.

On 1/9/2013 1:16 PM, Dávid Karnok wrote:
> Thanks for the replies.
>
> I tried to experiment with this mapMulti, but got a VerifyError (Netbeans 8
> 121214, Jdk 8 Lambda b72, Windows 7 x86) for the following program.
>
> import java.util.Arrays;
> import java.util.Iterator;
> import java.util.List;
> import java.util.function.MultiFunction;
> import java.util.stream.Spliterator;
> import java.util.stream.Stream;
> import java.util.stream.StreamOpFlag;
> import java.util.stream.Streams;
> public class SelectMany {
>      public static <T> Iterable<T> repeat(final T value) {
>          return () -> {
>              return new Iterator<T>() {
>                  public boolean hasNext() {
>                      return true;
>                  }
>                  public T next() {
>                      return value;
>                  }
>              };
>          };
>      }
>      public static <T> Stream<T> wrap(Iterable<T> source) {
>          return Streams.stream(
>                  Streams.spliteratorUnknownSize(
>                  source.iterator()), StreamOpFlag.NOT_SIZED);
>      }
>      public static void main(String[] args) {
>          List<Integer> list = Arrays.asList(1, 2, 3, 4);
>
>          MultiFunction<Integer, Integer> f = (c, t) ->
> c.yield(wrap(repeat(t)));
>
>          Stream<Integer> result = list.stream().mapMulti(f);
>
>          System.out.println(result.iterator().next());
>
>          System.out.println("Done.");
>      }
> }
>
> java.lang.VerifyError: Bad type on operand stack
> Exception Details:
>    Location:
>      SelectMany.repeat(Ljava/lang/Object;)Ljava/lang/Iterable; @2:
> invokedynamic
>    Reason:
>      Type 'java/lang/Object' (current frame, stack[0]) is not assignable to
> 'SelectMany'
>    Current Frame:
>      bci: @2
>      flags: { }
>      locals: { 'java/lang/Object' }
>      stack: { 'java/lang/Object', 'java/lang/Object' }
>    Bytecode:
>      0000000: 2a2a ba00 0200 00b0
>
> at java.lang.Class.getDeclaredMethods0(Native Method)
> at java.lang.Class.privateGetDeclaredMethods(Class.java:2442)
> at java.lang.Class.getMethod0(Class.java:2685)
> at java.lang.Class.getMethod(Class.java:1619)
> at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:521)
> at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:489)
> Exception in thread "main" Java Result: 1
>
> The build succeds without error.
>
> What I wanted is to see wether an infinite stream is realized in the
> MultiFunction or not if I only want one element through the contraption.
>
> 2013/1/9 Brian Goetz <brian.goetz at oracle.com>
>
>>   For example, the SelectMany operator, which takes a stream of Ts, and for
>>> each T, a new stream of Us is produced, and at the end, these U streams
>>> are
>>> flattened into a single stream of Us:
>>>
>>> Stream<U> selectMany(Stream<T>, Function<T, Stream<U>>);
>>>
>>
>> This is what we're currently calling mapMulti.
>>
>>
>>   I'm asking these because how default interface methods was chosen over C#
>>> style extension methods, where in the latter case I would just write a
>>> library for the operators and enjoy the dot-into simplicity. The former
>>> case leaves me (us) ask the owner of the particular interface for new
>>> default methods hopefully delivered in the next version, or stick with the
>>> static method call or wrapper-class approaches.
>>>
>>
>> On the other hand, you got virtual extension methods instead of static.
>>
>>
>
>
>
>
>


More information about the lambda-dev mailing list