Search code examples
javagenericsjava-streammethod-referencemodelmapper

ModelMapping a Stream without a Lambda Expression


I'm not Java developer, but I have many years of experience in C#. I have a List<Foo> that I need to convert to a List<Bar> using ModelMapper where Foo and Bar have essentially identical properties.

Currently I've written this as:

@AutoWired ModelMapper modelMapper;

...

List<Bar> results = repository
        .getFoos()
        .stream()
        .map(x -> modelMapper.map(x, Bar.class))
        .collect(Collectors.toList());

This works fine. However, I feel like that lambda expression could be replaced with just a simple method reference. If this were C#, I'd probably be able to do something along the lines of this:

var results = repository.getFoos().Select(modelMapper.map<Bar>).ToList();

But I can't find the right syntax in Java. I've tried this:

.map(modelMapper::<Bar>map)

But I get the error:

Cannot resolve method 'map'

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. In case it helps, the overload of map that I'm trying to use is defined as:

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

Is there any way to achieve this mapping without a lambda expression?


Solution

  • 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.

    You've not messed up the syntax; there's no equivalent in Java (it's often more verbose than C#, and streams are no exception.)

    You can only use the method reference (double colon) syntax when the parameters you want to pass to the method are the same, and in the same order, as the parameters in the functional interface.

    In the case of map, there's only one parameter, and you need to pass a second parameter (that being Bar.class) to modelMapper.map(), so no method reference syntax is allowed. The only way you could use it were if you were to subclass the modelMapper to work with Bar only, and therefore remove the need for the second explicit class parameter.

    I'm pretty confident that the method you're using there is the most concise way of doing things in Java.