Hello, Roger!

Thank you for looking at my proposal.

RR> What are the use cases?

It could be used to generate some per-day/per-month/per-year reports.
For example, consider you have a collection of Deal objects, each with
LocalDate:

List<Deal> deals;

Using Java-8 you can easily group them by date:

Map<LocalDate, List<Deal>> map = deals.stream()
   .collect(groupingBy(Deal::getDate));

Now suppose you want to know how many deals you have for each day in
the current month (including days when there are no deals). Using the
proposed API you may write:

YearMonth.now().days()
  .map(date -> date+": "+map.getOrDefault(date, 
Collections.emptyList()).size()+" deal(s)")
  .forEach(System.out::println);

RR> Does it need to be more convenient?
RR> It seems relatively easy to do in application code.

It's relatively easy, but it's necessary to refer to the temporal
object twice. Here's how it could be done now without creating
additional methods:

IntStream.range(1, YearMonth.now().lengthOfMonth())
  .mapToObj(YearMonth.now()::atDay)
  .map(...).forEach(...)

Such code may break when executed during the month change, so to make
it robust you should introduce a variable:

YearMonth now = YearMonth.now();
IntStream.range(1, now.lengthOfMonth())
  .mapToObj(now::atDay)
  .map(...).forEach(...)

Of course the static method could be introduced into some utility
class in the application:

public class DateStreams {
  public static Stream<LocalDate> days(YearMonth ym) {
    return IntStream.range(1, ym.lengthOfMonth()).mapToObj(ym::atDay);
  }
}

And used like this:

DateStreams.days(YearMonth.now())
  .map(date -> date+": "+map.getOrDefault(date, 
Collections.emptyList()).size()+" deal(s)")
  .forEach(System.out::println);

But having it in the JDK looks more natural. Especially given the fact
that java.time classes are final, so cannot be extended by some
third-party library.

RR> Could there be a more general form that would be as useful but add fewer
RR> methods?

Well for convenient use I cannot imagine how to reduce the number of
methods. It's possible to omit months() and days() and replace
year.months() with something like this:

year.atMonth(1).monthsUntil(year.plusYears(1).atMonth(1))

But it's even worse than not using the new API at all:

IntStream.range(1, 12).mapToObj(year::atMonth)

With best regards,
Tagir Valeev.

RR> Roger



RR> On 12/10/2015 11:31 AM, Tagir F. Valeev wrote:
>> Hello!
>>
>> Currently it seems that java.time package does not use Stream API in
>> any way. I think it would be nice to add some methods which produce
>> the streams. For example:
>>
>> - in class Year:
>>
>> // Returns sequential ordered stream of all months within this Year:
>> Stream<YearMonth> months();
>> // Returns sequential ordered stream of all days within this Year:
>> Stream<LocalDate> days();
>> // Returns sequential ordered stream of all years starting from this
>> // Year until the supplied year, exclusive
>> Stream<Year> yearsUntil(Temporal endExclusive);
>>
>> - in class YearMonth:
>>
>> // Returns sequential ordered stream of all days within this YearMonth:
>> Stream<LocalDate> days();
>> // Returns sequential ordered stream of all months starting from this
>> // YearMonth until the supplied YearMonth, exclusive
>> Stream<YearMonth> monthsUntil(Temporal endExclusive);
>>
>> - in class LocalDate:
>>
>> // Returns sequential ordered stream of all months starting from this
>> // LocalDate until the supplied LocalDate, exclusive
>> Stream<LocalDate> daysUntil(Temporal endExclusive);
>>
>> The implementation of these methods could be quite simple. For example:
>>
>> class Year {
>>    public Stream<LocalDate> days() {
>>      return IntStream.rangeClosed(1, length()).mapToObj(this::atDay);
>>    }
>> }
>>
>> What do you think?
>>
>> With best regards,
>> Tagir Valeev.
>>

Reply via email to