2017-02-16 13 views
3

Как мы можем использовать подход Java Streams для сбора объектов, сгенерированных в цикле for?Использовать потоки Java для сбора объектов, сгенерированных в цикле `for`

Например, здесь мы генерируем один объект LocalDate на каждый день в месяце, представленный YearMonth, повторно назову 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); 
} 

Можно ли это переписать с использованием потоков?

ответ

8

Его можно переписать начиная с IntStream:

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

Каждое целое значение от IntStream отображается на нужную дату, а затем даты собраны в списке.

+0

Что контролирует инстанциации 'list'? Каким будет конкретный объект за «Листом»? В [Answer by Górkiewicz] (http://stackoverflow.com/a/42285720/642706) я вижу, что мы явно определяем 'ArrayList'. Как эта задача выполняется здесь? Я вижу, что документ для 'toList' говорит:« Никаких гарантий по типу, изменчивости, сериализуемости или потокобезопасности возвращаемого списка ». Означает ли это, что базовый конкретный класс не является моим бизнесом или проблемой? Это было бы понятно и приемлемо; Мне просто интересно. –

+2

Вам нужен «Список », и вы получите именно это. Если вы хотите явно определить, какая реализация List должна использоваться, вы можете также: 'Collectors.toCollection (ArrayList :: new)' –

+0

'Collectors.toCollection (ArrayList :: new)' хорошо, но добавляет многословие. –

2

Замените ваш цикл с 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))); 
+0

Проголосовать? Как это не удачный ответ на вопрос? Пожалуйста, объясни. Этот ответ заработал мой голос. –

+0

Спасибо, Василий. Я не был достаточно быстрым: p –

+0

один минута здесь и там не заслуживает голосования. Заработал мой плюс один тоже (я не тот, кто голосует) –

1

В Java 9 специальный метод datesUntil добавляется LocalDate, который может генерировать поток дат:

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

 Смежные вопросы

  • Нет связанных вопросов^_^