Basil Bourque
Basil Bourque

Reputation: 340230

Use Java streams to collect objects generated in a `for` loop

How can we use the Java Streams approach to collecting objects generated in a for loop?

For example, here we generate one LocalDate object for each day in a month represented by YearMonth by repeatedly calling YearMonth::atDay.

YearMonth ym = YearMonth.of( 2017 , Month.AUGUST ) ;
List<LocalDate> dates = new ArrayList<>( ym.lengthOfMonth() );
for ( int i = 1 ; i <= ym.lengthOfMonth () ; i ++ ) {
    LocalDate localDate = ym.atDay ( i );
    dates.add( localDate );
}

Can this be rewritten using streams?

Upvotes: 3

Views: 280

Answers (3)

Tagir Valeev
Tagir Valeev

Reputation: 100329

In Java 9 a special method datesUntil is added to LocalDate which can generate a stream of dates:

LocalDate start = LocalDate.of(2017, Month.AUGUST, 1);
List<LocalDate> dates = start.datesUntil(start.plusMonths(1))
        .collect(Collectors.toList());

Upvotes: 1

Grzegorz G&#243;rkiewicz
Grzegorz G&#243;rkiewicz

Reputation: 4596

Replace your for loop with an IntStream:

YearMonth ym = YearMonth.of(2017, Month.AUGUST);
List<LocalDate> dates = new ArrayList<>(ym.lengthOfMonth());
IntStream.rangeClosed(1, ym.lengthOfMonth())
         .forEach(i -> dates.add(ym.atDay(i)));

Upvotes: 2

Markus Benko
Markus Benko

Reputation: 1507

It can be rewritten starting with an IntStream:

YearMonth ym = YearMonth.of(2017, Month.AUGUST);
List<LocalDate> dates =
        IntStream.rangeClosed(1, ym.lengthOfMonth())
        .mapToObj(ym::atDay)
        .collect(Collectors.toList());

Each integer value from the IntStream is mapped to the desired date and then the dates are collected in a list.

Upvotes: 8

Related Questions