To create a Stream
from Iterator
, you need to create Iterable
first and then pass its Spliterator
using Iterable::spliterator
method into StreamSupport::stream
.
Stream<?> stream = StreamSupport.stream(iterable.spliterator(), false);
The Iterable
can be created from Iterator
through a lambda expression as long as Iterable
has only one abstract method, therefore the interface is qualified for such expression.
Iterable<Company> iterable = () -> companyRepository.findAll();
Stream<Company> stream = StreamSupport.stream(iterable.spliterator(), false);
Now, the things get easy: Use the advantage of flatMap
to flatten the nested list structure (a list of companies where each company has a list of employees. You need to create each DataObject
right inside the flatMap
method as long as its instantiation relies on the company.getName()
parameter:
List<DataObject> dataObjectList = StreamSupport.stream(iterable.spliterator(), false)
.flatMap(company -> company.getEmployees().stream()
.map(employee -> {
DataObject dataObject = new DataObject();
dataObject.setCompanyName(company.getName());
dataObject.setEmployeeName(employee.getName());
return dataObject;
}))
.collect(Collectors.toList());
... and less verbose if you use a constructor ...
List<DataObject> dataObjectList = StreamSupport.stream(iterable.spliterator(), false)
.flatMap(company -> company.getEmployees().stream()
.map(employee -> new DataObject(company.getName(), employee.getName())))
.collect(Collectors.toList());