looking for FAQ on interconversion of IntFoo and Foo<Integer>

Howard Lovatt howard.lovatt at gmail.com
Tue Apr 16 18:25:06 PDT 2013


There is a way to get IntStream extends Stream<Integer> etc. to play well
with type inference.

1. Have interfaces such that the primitive form extends the reference form,
e.g.:

@FunctionalInterface public interface SupplierOfInt extends
Supplier<Integer> {
  default Integer get() { return getAsInt(); }
  int getAsInt();
}

2. Put all your makers, builders, factories, etc., in a single class for
each kind as static methods (i.e. do not have Arrays containing some,
Streams containing others etc. - one class containing all the makers). One
class per kind, i.e. Streams, StreamsOfInt, StreamsOfLong, and
StreamsOfDouble. EG:

import java.util.function.SupplierOfInt; // No need to import
java.util.function.Supplier
since it isn't needed and hence no inference problem

...

public final class StreamsOfInt {
  private StreamsOfInt() {}

  public static final SupplierOfInt forever(final int value) { return () ->
value; }

  ...
}

3. When you want to use StreamsOfInt you do a single static import when you
want to use a stream, e.g. import static java.util.stream.StreamsOfInt.*;

This way the compiler doesn't get confused because you have not imported
java.util.function.SupplierOfInt and java.util.function.Supplier into one
compilation unit (unlike the current package arrangement).

If you do statically import say Streams and StreamsOfInt into one
compilation unit you will have to qualify the start of the stream, e.g.
Streams.forever(new Object())... and StreamsOfInt.forever(1), and
importantly you do not have to qualify the rest of the stream code. In
practice I have found multiple stream source types rare in one file and
when you do have them the qualification is a good idea anyway.

I do this in my own stream library and it works great.

 -- Howard.

PS I also dropped the dot in Supplier.OfInt etc. since Netbeans hates this!
It also doesn't seem to add value and makes the Javadoc confusing.


On 16 April 2013 18:27, Remi Forax <forax at univ-mlv.fr> wrote:

> On 04/16/2013 09:01 AM, John Rose wrote:
> > Where is the standard place to find the design discussion for
> primitive-type specializations of the new interfaces (functions, producers,
> consumers, optionals...)?
> >
> > In particular, will users be able to ignore higher-order functions of
> unboxed values and later adjust code locally for efficiency?
> >
> > If so, are there conversion operators that correspond to auto-box and
> auto-unbox of non-functional, which can be used to make adjustments at the
> boundaries?
>
>  From the compiler point of view, in a lambda conversion Integer as is
> not a boxed int,
> so there is no such auto-boxing. Said differently a Stream of Integers
> and a Stream of ints are not the same object.
>
> >
> > Finally (and this is what prompted me to ask) why not make IntSupplier
> or OptionalInt be sub-interfaces of the reference-bearing ones, with
> autoboxing around the edges (see below)?
>
> At some point in the past, IntSupplier was a subtype of Supplier but it
> doesn't play well with type inference
> and method resolution in the compiler
> Supplier or IntSupplier because they are functional interface are seen
> by the compiler as structural types
> and mixing structural types and classical subtyping relationship has
> some hairy interactions.
>
> >
> > Since this is probably a rehash of past discussions, I'm looking to be
> pointed at some sort of Email thread or even (!) a wiki page.
> >
> > Best,
> > — John
>
> cheers,
> Rémi
>
> >
> > P.S. It looks like this sort of stuff was in the repo at first and then
> was yanked recently.
> >
> > diff --git a/src/share/classes/java/util/function/IntSupplier.java
> b/src/share/classes/java/util/function/IntSupplier.java
> > --- a/src/share/classes/java/util/function/IntSupplier.java
> > +++ b/src/share/classes/java/util/function/IntSupplier.java
> > @@ -32,7 +32,12 @@
> >   * @since 1.8
> >   */
> > @FunctionalInterface
> > -public interface IntSupplier {
> > +public interface IntSupplier
> > +    extends Supplier<Integer>
> > +{
> > +    /** Returns the result of {@code getAsInt}, boxed. */
> > +    // in my dreams, this would allows IntSupplier to convert to
> Supplier<Integer>
> > +    public default Integer get() { return getAsInt(); }
> >
> >      /**
> >       * Returns an {@code int} value.
> >
> >
>
>
>


-- 
  -- Howard.


More information about the lambda-libs-spec-observers mailing list