Possible JSR-310 (date/time API) stream methods

Brian Goetz brian.goetz at oracle.com
Thu Mar 7 12:48:32 PST 2013


More detail...

There's a ladder of ways to make a stream, in order of increasing work 
and increasing stream performance.

1.  Make an iterator.  If you have an Iterator, it's a one liner to make 
a stream.

2.  Make an iterator, plus also provide the size.  This yields a sized 
stream, which enables some additional optimizations such as optimized 
toArray calls.  Again, a one-liner.

3.  Make a spliterator.  This may be more work (or not, if you can build 
on existing spliterator tools), and will yield better parallel 
performance.

4.  Use an existing generator, like the kinds Zhong suggests.  One 
additional idiom that is often useful, besides iterate and friends, is 
this one, where you take a numeric range and map that:

   Stream<Foo> foos() {
       return Streams.range(0, numFoos).map(i -> getFoo(i));
   }

This one splits better than the obvious iterate-based equivalent.


On 3/7/2013 3:18 PM, Zhong Yu wrote:
> On Thu, Mar 7, 2013 at 1:57 PM, Stephen Colebourne <scolebourne at joda.org> wrote:
>> This is a call for opinions as to whether JSR-310 should think about
>> adding stream-based methods.
>>
>> It seems that the most likely use case is a stream of dates in a
>> range, either sequential or according to some rule. We already have a
>> "some rule" type concept in TemporalAdjuster, but that is general,
>> rather than LocalDate specific, so I've looked at UnaryOperator. One
>> possible pair of methods would be:
>>
>>   // methods on LocalDate
>>   public Stream<LocalDate> datesUntil(LocalDate endDate) {
>>     return datesUntil(endDate, d -> d.plusDays(1));
>>   }
>>   public Stream<LocalDate> datesUntil(LocalDate endDate,
>> UnaryOperator<LocalDate> generator) {
>>     // some code to generate a stream checking for being beyond the end date
>>     // initial perusal suggests this might be a little complex...
>>   }
>>
>>   // user code
>> startDate.datesUntil(endDate, d -> d.plusWeeks(1));
>> startDate.datesUntil(endDate, d -> d.with(nextHoliday()));
>>
>> Does the basic stream library support this kind of stuff without
>> JSR-310 needing to do it?
>> Does this look useful, or are there other/alternative more useful methods?
>> Should it only be for dates, or other objects like LocalDateTime or
>> ZonedDateTime?
>> Would it justify its place in the library given users could just write
>> a for loop?
>
> I'm sensing that you are asking for a factory method mimicing for-loop.
>
> Currently there is a
>
>      static<T> Stream<T> iterate(T seed, UnaryOperator<T> f)
>
> but it's infinite. How about
>
>      static<T> Stream<T> iterate(T init, Predicate<T> p, UnaryOperator<T> f)
>
> For example
>
>      iterate(startDate, d->d.isBefore(endDate), d->d.plusDays(1))
>
>
>> Any other thoughts?
>>
>> BTW, the following code wouldn't work as the user expects:
>>   startDate.datesUntil(endDate, d -> d.plusMonths(1));
>> (Jan31 + 1 month = Feb28 ... Feb28 + 1 month = March28!!)
>>
>> Stephen
>>
>


More information about the lambda-dev mailing list