在没有 Lambda 表达式的情况下对流进行模型映射
ModelMapping a Stream without a Lambda Expression
我不是 Java 开发人员,但我有多年的 C# 经验。我有一个 List<Foo>
,我需要使用 ModelMapper
将其转换为 List<Bar>
,其中 Foo
和 Bar
具有基本相同的属性。
目前我是这样写的:
@AutoWired ModelMapper modelMapper;
...
List<Bar> results = repository
.getFoos()
.stream()
.map(x -> modelMapper.map(x, Bar.class))
.collect(Collectors.toList());
这很好用。但是,我觉得 lambda 表达式可以只用一个简单的方法引用来代替。如果这是 C#,我可能可以按照以下方式做一些事情:
var results = repository.getFoos().Select(modelMapper.map<Bar>).ToList();
但我在 Java 中找不到正确的语法。我试过这个:
.map(modelMapper::<Bar>map)
但我得到错误:
Cannot resolve method 'map
'
我不确定这是因为我以某种方式混淆了语法,还是因为 map 方法有太多重载而无法创建明确的引用。如果有帮助,我尝试使用的 map
的重载定义为:
public <D> D map(Object source, Class<D> destinationType)
有没有什么方法可以不用 lambda 表达式来实现这个映射?
I am not sure if this is because I've mixed up the syntax somehow, or this is because the map method has a too many overloads to create an unambiguous reference.
你没有搞错语法; Java 中没有等效项(它通常比 C# 更冗长,流也不例外。)
当您要传递给方法的参数与功能接口中的参数相同且顺序相同时,您只能使用方法引用(双冒号)语法。
在map
的情况下,只有一个参数,需要传递第二个参数(即Bar.class
)给modelMapper.map()
,所以没有方法引用语法允许。您 可以 使用它的唯一方法是,如果您将 class 子 modelMapper
仅与 Bar
一起使用,因此不需要第二个显式 class 参数。
我非常有信心您使用的方法是 Java 中最简洁的处理方式。
实际上这是做不到的,因为你的modelMapper.map()
方法需要两个参数。如果此时你真的想使用方法引用,你可以在 modelMapper
中创建一个新方法,它只需要一个参数,或者将 modelMapper.map()
调用包装在另一个方法中,如下所示:
private Bar mapFooToBar(Foo x) {
return modelMapper.map(x, Bar.class);
}
您现在可以通过方法参考使用此方法:
List<Bar> results = repository.getFoos().stream()
.map(this::mapFooToBar)
.collect(Collectors.toList());
但最后我认为这不会以任何方式使您的代码变得更好,因此我建议使用您已有的 lambda 表达式。
Java 不支持 partial function application (related to currying),因此您只能使用 lambda 来实现。
当然,由于您不引用任何 local 变量或参数,您可以定义一个方法,然后您可以 reference .
@AutoWired ModelMapper modelMapper;
private Bar mapToBar(Foo x) {
return modelMapper.map(x, Bar.class);
}
...
List<Bar> results = repository
.getFoos()
.stream()
.map(this::mapToBar)
.collect(Collectors.toList());
这实际上与 lambda 的编译方式非常接近,只是 lambda 的 mapToBar
将是一个隐藏(合成)方法。
我不是 Java 开发人员,但我有多年的 C# 经验。我有一个 List<Foo>
,我需要使用 ModelMapper
将其转换为 List<Bar>
,其中 Foo
和 Bar
具有基本相同的属性。
目前我是这样写的:
@AutoWired ModelMapper modelMapper;
...
List<Bar> results = repository
.getFoos()
.stream()
.map(x -> modelMapper.map(x, Bar.class))
.collect(Collectors.toList());
这很好用。但是,我觉得 lambda 表达式可以只用一个简单的方法引用来代替。如果这是 C#,我可能可以按照以下方式做一些事情:
var results = repository.getFoos().Select(modelMapper.map<Bar>).ToList();
但我在 Java 中找不到正确的语法。我试过这个:
.map(modelMapper::<Bar>map)
但我得到错误:
Cannot resolve method '
map
'
我不确定这是因为我以某种方式混淆了语法,还是因为 map 方法有太多重载而无法创建明确的引用。如果有帮助,我尝试使用的 map
的重载定义为:
public <D> D map(Object source, Class<D> destinationType)
有没有什么方法可以不用 lambda 表达式来实现这个映射?
I am not sure if this is because I've mixed up the syntax somehow, or this is because the map method has a too many overloads to create an unambiguous reference.
你没有搞错语法; Java 中没有等效项(它通常比 C# 更冗长,流也不例外。)
当您要传递给方法的参数与功能接口中的参数相同且顺序相同时,您只能使用方法引用(双冒号)语法。
在map
的情况下,只有一个参数,需要传递第二个参数(即Bar.class
)给modelMapper.map()
,所以没有方法引用语法允许。您 可以 使用它的唯一方法是,如果您将 class 子 modelMapper
仅与 Bar
一起使用,因此不需要第二个显式 class 参数。
我非常有信心您使用的方法是 Java 中最简洁的处理方式。
实际上这是做不到的,因为你的modelMapper.map()
方法需要两个参数。如果此时你真的想使用方法引用,你可以在 modelMapper
中创建一个新方法,它只需要一个参数,或者将 modelMapper.map()
调用包装在另一个方法中,如下所示:
private Bar mapFooToBar(Foo x) {
return modelMapper.map(x, Bar.class);
}
您现在可以通过方法参考使用此方法:
List<Bar> results = repository.getFoos().stream()
.map(this::mapFooToBar)
.collect(Collectors.toList());
但最后我认为这不会以任何方式使您的代码变得更好,因此我建议使用您已有的 lambda 表达式。
Java 不支持 partial function application (related to currying),因此您只能使用 lambda 来实现。
当然,由于您不引用任何 local 变量或参数,您可以定义一个方法,然后您可以 reference .
@AutoWired ModelMapper modelMapper;
private Bar mapToBar(Foo x) {
return modelMapper.map(x, Bar.class);
}
...
List<Bar> results = repository
.getFoos()
.stream()
.map(this::mapToBar)
.collect(Collectors.toList());
这实际上与 lambda 的编译方式非常接近,只是 lambda 的 mapToBar
将是一个隐藏(合成)方法。