猿问

在没有 Lambda 表达式的情况下对流进行模型映射

我不是 Java 开发人员,但我有多年的 C# 经验。我有一个List<Foo>,我需要转换为一个List<Bar>using ModelMapperwhereFoo并且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)

但我得到错误:


无法解析方法“ map”


我不确定这是因为我以某种方式混淆了语法,还是因为 map 方法有太多重载而无法创建明确的引用。如果有帮助,map我尝试使用的重载定义为:


public <D> D map(Object source, Class<D> destinationType)

没有 lambda 表达式,有什么方法可以实现此映射?


三国纷争
浏览 101回答 3
3回答

繁星点点滴滴

我不确定这是因为我以某种方式混淆了语法,还是因为 map 方法有太多重载而无法创建明确的引用。你没有弄乱语法;Java 中没有等效项(它通常比 C# 更冗长,流也不例外。)当您要传递给方法的参数与功能接口中的参数相同且顺序相同时,您只能使用方法引用(双冒号)语法。在 的情况下map,只有一个参数,您需要将第二个参数(即Bar.class)传递给modelMapper.map(),因此不允许使用方法引用语法。您可以使用它的唯一方法是,如果您要将其子类化modelMapper以Bar仅使用它,从而消除对第二个显式类参数的需要。我非常有信心您在此处使用的方法是 Java 中最简洁的处理方式。

慕运维8079593

Java 不支持部分函数应用(与柯里化相关),因此您只能使用 lambda 来做到这一点。当然,由于您不引用任何局部变量或参数,您可以定义一个方法,然后再引用它。@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 的编译方式,除了mapToBarlambda 是一个隐藏的(合成的)方法。

九州编程

实际上这是做不到的,因为你的modelMapper.map()方法需要两个参数。如果此时你真的想使用方法引用,你可以在你的 中创建一个新方法modelMapper,它只需要一个参数或将调用包装modelMapper.map()在另一个方法中,如下所示:private&nbsp;Bar&nbsp;mapFooToBar(Foo&nbsp;x)&nbsp;{&nbsp; &nbsp;&nbsp;&nbsp;return&nbsp;modelMapper.map(x,&nbsp;Bar.class); }您现在可以将此方法与方法参考一起使用:List<Bar>&nbsp;results&nbsp;=&nbsp;repository.getFoos().stream() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.map(this::mapFooToBar) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());但最后我认为这不会使您的代码以任何方式变得更好,所以我建议使用您已有的 lambda 表达式。
随时随地看视频慕课网APP

相关分类

Java
我要回答