转换为列表<;另一个目标>;从列表<;对象>;,列表<;对象>;使用streams Java 8

转换为列表<;另一个目标>;从列表<;对象>;,列表<;对象>;使用streams Java 8,java,java-8,mapping,java-stream,Java,Java 8,Mapping,Java Stream,我有两个相同类型的列表 class Orders { Strig User; String tradeDate; BigDecimal Qty; } 比较之后,我想转换成另一个对象的列表,比如 class DiffOrders { String User; String tradeDate; BigDecimal currentQty; BigDecimal prevQty; } 我有两份订单单

我有两个相同类型的列表

class Orders {
    Strig User;
    String tradeDate;
    BigDecimal Qty;
}
比较之后,我想转换成另一个对象的列表,比如

class DiffOrders {
        String User;
        String tradeDate;
        BigDecimal currentQty;
        BigDecimal prevQty;
    }
我有两份订单单

List<Orders>currentOrders;
List<Orders>prevOrders;

   List<Orders> DiffOrders = current.stream()
                                       .filter(curr->previous.stream().anyMatch(prev->OrderPredicate.orderDiffSize(curr, prev)))
                                       .collect(Collectors.toList());
ListcurrentOrders;
列表命令;
List DiffOrders=current.stream()
.filter(curr->previous.stream().anyMatch(prev->OrderPredicate.orderDiffSize(curr,prev)))
.collect(Collectors.toList());
对于同一日期和同一用户的订单,我希望捕获匹配订单中的数量

我能够找到匹配的
列表。但不确定如何捕获并转换为新类的
列表。你能帮忙吗

编辑1: OrderPredicate.orderDiffSize是一个比较 当前和以前订单的用户、交易日期、数量和符号(+表示出售,-表示购买)。此处未提供简要说明

编辑2: 上一个/当前列表的大小是合理的,可以忽略o log n计算问题

编辑3: 删除方向以保持简单。
例如,我分别在7月1日、7月2日和7月3日收到了prevOrders和CurrentOrders的订单。如果同一日期的订单数量不同,我想将其放在不同的订单中,数量来自当前和以前。希望这能说明问题。

据我所知,问题的主要需求之一是当前和以前的
顺序的映射,以便您可以根据细节构建
匹配顺序。当然,这将需要一个
映射
操作以及
过滤器
,在将当前条目构建到以前条目的过程中

List<MatchOrders> matchedOrders = currentOrders.stream()
        .map(curr -> new AbstractMap.SimpleEntry<>(curr, prevOrders.stream()
                .filter(prev -> orderSameDirectionAndSize(curr, prev))
                .findAny())) // <Order, Optional<Order>> currentToOptionalPrevious
        .map(e -> {
            Orders current = e.getKey();
            Orders previous = e.getValue().orElse(current); // assumed a fallback
            return new MatchOrders(current.getUser(), current.getQty(),
                    previous.getQty(), current.getDirection(), previous.getDirection());
        })
        .collect(Collectors.toList());
List matchedOrders=currentOrders.stream()
.map(curr->newAbstractMap.SimpleEntry(curr,prevOrders.stream())
.filter(prev->OrderSameDirection和Size(curr,prev))
.findAny())//currentToOptionalPrevious
.map(e->{
当前订单=e.getKey();
Orders previous=e.getValue().orElse(当前);//假定为回退
返回新的匹配订单(current.getUser(),current.getQty(),
previous.getQty()、current.getDirection()、previous.getDirection());
})
.collect(Collectors.toList());

听起来这个问题的症结在于,您想省略
当前
中任何在
上一个
中没有匹配项的项,但要使用
上一个
中的实际对应值转换有匹配项的项。在这种情况下,
flatMap
就是您想要的。您可以使用
flatMap
将每个
Order
转换为
DiffOrders
,而不是转换为一个
DiffOrders
流,该流对于非匹配项为空,对于匹配项由单个元素组成

List<DiffOrders> matchedOrders = current.stream()
    .flatMap(curr -> {
      Optional<Order> p = previous.stream()
          .filter(prev -> OrderPredicate.orderSameDirectionAndSize(curr, prev))
          .findFirst();
      if (p.isPresent() && !p.get().qty.equals(curr.qty)) {
        return Stream.of(new DiffOrders(curr.user, curr.tradeDate, curr.qty, p.get().qty));
      } else {
        return Stream.empty();
      }
    }) 
    .collect(Collectors.toList());
List matchedOrders=current.stream()
.flatMap(当前->{
可选p=previous.stream()
.filter(prev->OrderPredicate.OrderSameDirection和Size(curr,prev))
.findFirst();
如果(p.isPresent()&&!p.get()。数量等于(当前数量)){
返回流(新的DiffOrders(curr.user、curr.tradeDate、curr.qty、p.get().qty));
}否则{
返回Stream.empty();
}
}) 
.collect(Collectors.toList());

对于简单代码和简单算法,分两步解决

private List<DiffOrders>  mergeLists(List<Orders> currentOrders, List<Orders> prevOrders) {
    Map<String, List<Orders>> map = prevOrders.stream().collect(Collectors.groupingBy(order -> order.getUser() + order.getTradeDate()));
    return currentOrders.stream().filter(current ->{
       String key = current.getUser() + current.getTradeDate();
       return map.get(key) != null && !map.get(key).isEmpty();
   }).map(current -> mapper(current, map.get(current.getUser() + current.getTradeDate()))).collect(Collectors.toList());
}

private DiffOrders mapper(Orders current, List<Orders> list) {
    DiffOrders diffOrders = new DiffOrders();
    diffOrders.setCurrentQty(current.getQty());
    diffOrders.setTradeDate(current.getTradeDate());
    diffOrders.setUser(current.getUser());
    diffOrders.setPrevQty(list.get(0).getQty());
    return diffOrders;
}
private List合并列表(List currentOrders,List prevOrders){
Map Map=prevOrders.stream().collect(Collectors.groupingBy(order->order.getUser()+order.getTradeDate());
return currentOrders.stream().filter(当前->{
字符串键=current.getUser()+current.getTradeDate();
return map.get(key)!=null&&!map.get(key).isEmpty();
}).map(current->mapper(current,map.get(current.getUser()+current.getradedate()))).collect(Collectors.toList());
}
专用DiffOrders映射器(当前订单,列表){
DiffOrders DiffOrders=新的DiffOrders();
diffOrders.setCurrentQty(current.getQty());
setTradeDate(current.getTradeDate());
setUser(current.getUser());
setPrevQty(list.get(0.getQty());
退回订单;
}

MatchOrders
类中当前/以前的方向和数量是多少?你能添加一个输入和输出示例来解释这一点吗?我很难完全理解你需要什么。如果您希望更改流的元素(例如,从
Stream
开始,以
Stream
结束,映射是您的朋友,即:
map
函数,它要求您指定如何将
Order
转换为
MatchedOrder
。简单的输入和输出将非常有帮助。我建议您首先编写它,而不使用streams进行理解。)以及您通常需要的操作。然后您可以将这些相同的操作放在流形式中,这应该非常简单。哎呀,错误地记住了
findFirst
API。现在修复了。