Как переделать цикл в стрим?
Есть метод, который получает данные из класса и собирает в нужном формате в лист. Я реализовал это с помощью цикла, но необходимо использовать прелести JAVA 8 API, поэтому пытался заменить цикл на работу с .stream(), но пока безуспешно. Как это можно сделать?
private ArrayList<String> collectReport() {
String timeFormat = "m:ss.SSS";
String reportFormat = "%d. %s | %s | %s";
int counter = 0;
ArrayList<String> list = new ArrayList<>();
for (ReportRecord dataRecord : recordList) {
String name = dataRecord.getName();
String team = dataRecord.getTeam();
String time = LocalTime.ofNanoOfDay(dataRecord.getTimeDiff()).format(DateTimeFormatter.ofPattern(timeFormat));
list.add(String.format(reportFormat, (1 + counter++), name, team, time));
if (counter == 15) {
list.add("—".repeat(60));
}
}
return list;
}
Ответы (1 шт):
Имеет смысл создать отдельный метод для преобразования в строку элемента списка recordList, затем использовать IntStream для получения стрима индексов и преобразования индексов в строки.
private String recordToString(int index) {
String timeFormat = "m:ss.SSS";
String reportFormat = "%d. %s | %s | %s";
ReportRecord dataRecord = recordList.get(index);
String name = dataRecord.getName();
String team = dataRecord.getTeam();
String time = LocalTime.ofNanoOfDay(dataRecord.getTimeDiff()).format(DateTimeFormatter.ofPattern(timeFormat));
return String.format(reportFormat, 1 + index, name, team, time);
}
// вернуть только строки исходного списка
private List<String> collectReport() {
return IntStream.range(0, recordList.size())
.mapToObj(this::recordToString)
.collect(Collectors.toList());
}
Разделители можно добавить отдельно.
В Java 16 и выше можно использовать метод Stream::toList для получения немодифицируемого списка строк.
Однако, если строки-разделители обязательно должны быть в результирующем списке в качестве отдельного элемента, можно слегка модифицировать представленный метод recordToString, чтобы он возвращал стрим строк, к которым затем потребуется применить операцию Stream::flatMap.
Также, для получения конкретной реализации ArrayList<String> можно использовать коллектор Collectors.toCollection(ArrayList::new) вместо привычного Collectors.toList().
private Stream<String> recordToStream(int index) {
String timeFormat = "m:ss.SSS";
String reportFormat = "%d. %s | %s | %s";
String delimiter = "-".repeat(60);
ReportRecord dataRecord = recordList.get(index);
String name = dataRecord.getName();
String team = dataRecord.getTeam();
String time = LocalTime.ofNanoOfDay(dataRecord.getTimeDiff()).format(DateTimeFormatter.ofPattern(timeFormat));
String result = String.format(reportFormat, 1 + index, name, team, time);
return (1 + index) % 15 == 0
? Stream.of(result, delimiter)
: Stream.of(result);
}
// вернуть строки исходного списка с разделителями
private ArrayList<String> collectReport() {
return IntStream.range(0, recordList.size())
.mapToObj(this::recordToStream) // Stream<Stream<String>>
.flatMap(s -> s) // Stream<String>, вариант .flatMap(Function.identity())
.collect(Collectors.toCollection(ArrayList::new));
}