overloads for java.util.RandomAccess

Brian Goetz brian.goetz at oracle.com
Wed Oct 31 06:39:52 PDT 2012


I agree on the problem you're trying to solve, but there's a better solution.  

The Streams.stream(List) method should not exist.  Instead, we should use list.stream() so that the implementation can overload correctly; instanceof RandomAccess is a hack.  The methods in Streams should be for low-level stream construction, not getting a stream from things that are already Streamable.  These are in need of some refactoring, so stay tuned.  

On Oct 31, 2012, at 3:54 AM, Gernot Neppert wrote:

> Sorry, googlemail interpreted some key that I pressed (I don't know which
> one, unfortunately) to send the previous mail without my intent...
> I continue here:
> 
> So, I suggest to replace it with the following overload which takes the
> established approach of testing for 'RandomAccess' explicitly:
> 
> public static <T> Stream<T> stream(List<T> source) {
>    if(source instanceof RandomAccess) {
>        return new ValuePipeline<>(new
> RandomAccessListStreamAccessor<T>(source));
>    }
>    return new ValuePipeline<>(new TraversableStreamAccessor<>(source,
> source.size()));
> }
> 
> 
> As you can see, I've also implicitly changed the type parameter(s) of
> 'RandomAccessListStreamAccessor' so that it works on java.util.List
> directly.
> 
> (Note: The current version has a performance issue, as the erased argument
> type is not java.util.List, but rather java.util.RandomAccess, and there's
> an invisible checked cast involved in every single invocation of any of
> List's methods. Probably not what the author intended)
> 
> 
> 
> 
> 
> 
> 
> 2012/10/31 Gernot Neppert <mcnepp02 at googlemail.com>
> 
>> Hello all,
>> 
>> while trying to get an overview of the various factory methods in
>> java.util.streams.Streams, it grabbed my attention that the 'tagging
>> interface' java.util.RandomAccess has been chosen there as an overload
>> discriminator. I think that's a premiere in the entire JDK!
>> 
>> Take a look at this one, for example:
>> 
>>    public static <T, L extends RandomAccess & List<T>> Stream<T> stream(L
>> source) ;
>> 
>> This overload will obviously only be picked by the compiler if a 'source'
>> is passed whose static type implements java.util.RandomAccess, such as
>> java.util.ArrayList. Should you invoke it in a context where the static
>> type is 'java.util.List<T>', it will not be picked, and the overload
>> 
>>    public static<T> Stream<T> stream(Collection<T> source);
>> 
>> will be picked instead. This is very likely to happen, which would be a
>> shame!
>> 
>> So, I suggest to replace it with the following overload which takes the
>> established approach of testing for 'RandomAccess' explicitly:
>> 
>> public static <T> Stream<T> stream(List<T> source) {
>> if(source instanceof RandomAccess) {
>>        return new ValuePipeline<>(new
>> RandomAccessListStreamAccessor<T,L>(source));
>>    }
>> 
>> 
>> 
>> 
>> 
>> 
> 



More information about the lambda-dev mailing list