Simon Schüpbach Simon Schüpbach - 5 months ago 8
Java Question

Java streams, create new object based on two different objects

What is the best way to create a new object based on two different objects.

I would like to use java streams.

My two start objects

public class EventA{
Long id;
String name;
...
Long locationID;
}

public class EventB{
Long id
String Name;
...
Long locationID;
}


And my result class

public class Result{
Long locationID;
String eventAName;
String eventBName;

public Result(...){...}
}


I have two object arrays like

List<EventA> eventAList;
List<EventB> eventBList;


I like to get an array of Result objects. Every EventA name should be copied to the resultList. If an EventB at the same location exists I would like to save the name in eventBName.

All I have done so far is

List<Result> resultList = eventAList.stream().map(e -> new Result(e.locationID, e.name, null)).collect(Collectors.toList());


I don't know how to pass the value from EventB to the constructor

Answer

When creating your Result, you can use a stream to iterate on the values in eventBList to retain only the ones with the same locationID as your eventAList value, then take the value you found, and map() it to it's Name value, or null if it doesn't exists:

List<Result> resultList = eventAList.stream().map(a -> new Result(a.locationID, a.name,
    eventBList.stream().filter(b -> b.locationID.equals(a.locationID)).findAny().map(b -> b.Name).orElse(null)
)).collect(Collectors.toList());

For better performances, you can use a temporary Map:

final Map<Long, String> eventBMap = eventBList.stream().collect(Collectors.toMap(b -> b.locationID, b -> b.Name));

List<Result> resultList = eventAList.stream().map(a -> new Result(a.locationID, a.name,
    eventBMap.get(a.locationID)
)).collect(Collectors.toList());