Java 从列表列表以功能方式创建列表的最干净方法是什么?

Java 从列表列表以功能方式创建列表的最干净方法是什么?,java,functional-programming,java-stream,Java,Functional Programming,Java Stream,我有以下代码: List<DataObject> dataObjectList = new ArrayList<>(); for (Company company : companyRepository.findAll()) { for (Employee employee : company.employees) { DataOjbect dataObject = new dataObject(); dataObject.setC

我有以下代码:

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);
    }
}
List dataObjectList=new ArrayList();
for(公司:companyRepository.findAll()){
用于(员工:公司。员工){
DataOjbect dataObject=新的dataObject();
dataObject.setCompanyName(company.getName());
dataObject.setEmployeeName(employee.getName());
dataObjectList.add(dataObject);
}
}
用java编写函数式代码最干净的方法是什么


请注意,
companyRepository.findAll()
返回一个迭代器,因此不能简单地从中创建流。

要从
迭代器创建
,您需要首先创建
Iterable
,然后使用
Iterable::Spliterator
方法将其
Spliterator
传递到
StreamSupport::stream

Stream<?> stream = StreamSupport.stream(iterable.spliterator(), false);
现在,事情变得简单了:利用
flatMap
的优势来扁平化嵌套的列表结构(每个公司都有一个员工列表的公司列表。您需要在
flatMap
方法中创建每个
DataObject
,只要其实例化依赖于
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 dataObjectList=StreamSupport.stream(iterable.spliterator(),false)
.flatMap(公司->公司.getEmployees().stream())
.map(员工->{
DataObject DataObject=新的DataObject();
dataObject.setCompanyName(company.getName());
dataObject.setEmployeeName(employee.getName());
返回数据对象;
}))
.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());
List dataObjectList=StreamSupport.stream(iterable.spliterator(),false)
.flatMap(公司->公司.getEmployees().stream())
.map(employee->newdataobject(company.getName(),employee.getName()))
.collect(Collectors.toList());

在我看来,使用streams来实现这一点并没有什么真正的好处。我会坚持你所拥有的。你可以通过在你的
数据对象
类中创建一个
构造函数
来让它更简洁。然后你可以做以下事情:

List<DataObject> dataObjectList = new ArrayList<>();

for (Company company : companyRepository.findAll()) {
    for (Employee employee : company.employees) {
        dataObjectList.add(new DataObject(company.getName(), employee.getName()));
    }
}
List dataObjectList=new ArrayList();
for(公司:companyRepository.findAll()){
用于(员工:公司。员工){
添加(新的数据对象(company.getName(),employee.getName());
}
}

“请注意,
companyRepository.findAll()
返回一个迭代器,因此不能简单地从迭代器中创建流。”将
map
提升到管道的顶层,并将
flatMap
限制在
company.getEmployees().stream()可能会更清晰一些
@chrylis谨慎的光学-我想我不明白你的意思。你会提供自己的答案还是通过类似的方式提供代码?即使他们特别要求“功能性”方式,有时还是最好使用KIS,坚持使用有效且可读的方式。+1
List<DataObject> dataObjectList = new ArrayList<>();

for (Company company : companyRepository.findAll()) {
    for (Employee employee : company.employees) {
        dataObjectList.add(new DataObject(company.getName(), employee.getName()));
    }
}