Initial prototype for BiStream

Peter Levart peter.levart at gmail.com
Mon Apr 23 11:26:59 PDT 2012


On Saturday, April 21, 2012 01:51:02 PM Brian Goetz wrote:
> Another of the "open issues" is whether the two-valued stream 
> should be considered a stream of pair objects (boxing issues), an 
> undifferentiated two-valued stream (which requires addressing the above 
> question: what does a bi-valued iterator look like?),

An awkward-looking BiIterator?


public interface BiIterator<T, U> extends Iterator<BiValue<T, U>>
{
   /**
    * @return the left value of the next BiValue element in the iteration
    * @throws java.util.NoSuchElementException if the iteration has no more elements
    */
   T nextLeft() default {
       return next().left();
   }

   /**
    * @return the left value of the last BiValue element returned by this iterator.  This method can be called
    *         only after call to {@link #next}, {@link #nextLeft()} or {@link #nextRight()}.
    * @throws IllegalStateException if neither of {@link #next}, {@link #nextLeft()} or {@link #nextRight()}
    *         methods has been been called, or the {@link #remove()} method has been called afterwards.
    */
   T currentLeft() default {
       current().left();
   }

   /**
    * @return the right value of the next BiValue element in the iteration
    * @throws java.util.NoSuchElementException if the iteration has no more elements
    */
   U nextRight() default {
       return next().right();
   }

   /**
    * @return the right value of the last BiValue element returned by this iterator.  This method can be called
    *         only after call to {@link #next}, {@link #nextLeft()} or {@link #nextRight()}.
    * @throws IllegalStateException if neither of {@link #next}, {@link #nextLeft()} or {@link #nextRight()}
    *         methods has been been called, or the {@link #remove()} method has been called afterwards.
    */
   U currentRight()  {
      current().right();
   }

   /**
    * @return the last BiValue element returned by this iterator.  This method can be called
    *         only after call to {@link #next}, {@link #nextLeft()} or {@link #nextRight()} and not after {@link #remove()}.
    * @throws IllegalStateException if neither of {@link #next}, {@link #nextLeft()} or {@link #nextRight()}
    *         methods has been been called, or the {@link #remove()} method has been called afterwards.
    */
   BiValue<T, U> current();
}


// also, the corresponting BiIterable (returned from BiStream.asIterable()) would be needed too:

public interface BiIterable<T, U> extends Iterable<BiValue<T, U>>
{
   @Override
   BiIterator<T, U> iterator();
}


// a loop over left/right elements with no BiValue boxing then becomes:

for (
    BiIterator<K, V> iter = biStream.asIterable().iterator();
    iter.hasNext();
) {
   System.out.println("left: " + iter.nextLeft() + ", right: " + iter.currentRight());
}


// and one of BiStream.map default methods could be rewriten as:

    <V> BiStream<T, V> map(final BiMapper<T, U, V> mapper) default {
        return new BiStream<T, V>() {

            // some methods skiped ...

            @Override
            public BiIterable<T, V> asIterable() {
                return new BiIterable<T, V>() {

                    @Override
                    public boolean isEmpty() {
                        return BiStream.this.isEmpty();
                    }

                    @Override
                    public BiIterator<T, V> iterator() {
                        return new BiIterator<T, V>() {

                            final BiIterator<T, U> source = BiStream.this.asIterable().iterator();
                            
                            @Override
                            public boolean hasNext() {
                                return source.hasNext();
                            }

                            @Override
                            public T nextLeft() {
                                return source.nextLeft();
                            }

                            @Override
                            public V nextRight() {
                                return mapper.map(source.nextLeft(), source.currentRight());
                            }

                            @Override
                            public BiValue<T, V> next() {
                                return new BiVal<>(nextLeft(), currentRight());
                            }

                            @Override
                            public BiValue<T, V> currentLeft() {
                                return source.currentLeft();
                            }

                            @Override
                            public BiValue<T, V> currentRight() {
                                return mapper.map(source.currentLeft(), source.currentRight());
                            }

                            @Override
                            public BiValue<T, V> current() {
                                return new BiVal<>(currentLeft(), currentRight());
                            }
                        };
                    }
                };
            }
        };
    }
 

Regards,

Peter


More information about the lambda-dev mailing list