我有以下代码:
List<DataObject> dataObjectList = new ArrayList<>();
for (Company company : companyRepository.findAll()) {
for (Employee employee : company.employees) {
DataOjbect dataObject = new dataObject();
dataObject.setCompanyName(company.getName());
dataObject.setEmployeeName(employee.getName());
dataObjectList.add(dataObject);
}
}
在Java中以功能样式编写此代码的最干净的方法是什么?
请注意,companyRepository.findAll()
返回一个Iterator,因此您不能简单地从其中创建一个流。
答案 0 :(得分:2)
要从Stream
创建Iterator
,您需要先创建Iterable
,然后使用Spliterator
方法将其Iterable::spliterator
传递到StreamSupport::stream
Stream<?> stream = StreamSupport.stream(iterable.spliterator(), false);
只要Iterable
仅具有一个抽象方法,就可以从Iterator
通过lambda表达式创建Iterable
,因此该接口符合该表达式的要求。
Iterable<Company> iterable = () -> companyRepository.findAll();
Stream<Company> stream = StreamSupport.stream(iterable.spliterator(), false);
现在,事情变得简单了:利用flatMap
的优势来简化嵌套列表结构(每个公司都有员工列表的公司列表。您需要正确创建每个DataObject
只要其实例化依赖于flatMap
参数,就可以在company.getName()
方法中使用
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());
...,如果使用构造函数,则不那么冗长...
List<DataObject> dataObjectList = StreamSupport.stream(iterable.spliterator(), false)
.flatMap(company -> company.getEmployees().stream()
.map(employee -> new DataObject(company.getName(), employee.getName())))
.collect(Collectors.toList());
答案 1 :(得分:1)
Imo,使用流执行此操作并没有真正的好处。我会坚持你所拥有的。通过在您的constructor
类中创建一个DataObject
,可以使其更加简洁。然后您可以执行以下操作:
List<DataObject> dataObjectList = new ArrayList<>();
for (Company company : companyRepository.findAll()) {
for (Employee employee : company.employees) {
dataObjectList.add(new DataObject(company.getName(), employee.getName()));
}
}