Java流,基于两个不同的对象

时间:2016-06-23 08:52:32

标签: java lambda java-stream

基于两个不同的对象创建新对象的最佳方法是什么。

我想使用java流。

我的两个开始对象

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

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

我的结果类

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

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

我有两个像

这样的对象数组
List<EventA> eventAList;
List<EventB> eventBList;

我想获得一组 Result 对象。应将每个 EventA 名称复制到resultList。如果存在同一位置的 EventB ,我希望将该名称保存在 eventBName 中。

到目前为止我所做的一切都是

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

我不知道如何将 EventB 中的值传递给构造函数

3 个答案:

答案 0 :(得分:2)

创建Result时,您可以使用流来迭代eventBList中的值,以仅保留与locationID值具有相同eventAList的值,然后获取您找到的值,map()将其设为Name值,或null如果它不存在:

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());

为了获得更好的表现,您可以使用临时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());

答案 1 :(得分:1)

我找到了一种工作方式

我将 Result 类的构造函数调整为

public Result(Long locationID, String eventAName, EventB eventB){
    this.locationID = locationID;
    this.eventAName = eventAName;
    this.eventBName = eventB.name;
}

然后在我的java流中

List<Result> resultList = eventAList.stream().map(ea -> new Result(ea.locationID, ea.name, eventBList.stream().filter(eb -> eb.locationID.equals(ea.locationID)).findFirst().orElse(new EventB()).get()).collect(Collectors.toList());

答案 2 :(得分:1)

您可以执行以下操作,然后处理增强功能(例如,通过locationId为eventBlist创建一个地图作为键,以便更快地进行搜索)

Function<EventA, SimpleEntry<EventA, Optional<EventB>>> mapToSimpleEntry = eventA -> new SimpleEntry<>(eventA,
    eventBList.stream()
    .filter(e -> Objects.equals(e.getLocationID(), eventA.getLocationID()))
    .findFirst());

Function<SimpleEntry<EventA, Optional<EventB>>, Result> mapToResult = simpleEntry -> {
    EventA eventA = simpleEntry.getKey();
    Optional<EventB> eventB = simpleEntry.getValue();
    return new Result(eventA.getLocationID(), eventA.getName(), eventB.map(EventB::getName).orElse(null));
};

eventAList.stream()
    .map(mapToSimpleEntry)
    .map(mapToResult)
    .collect(Collectors.toList());