有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用streams Java 8从List<Object>、List<Object>转换为List<AnotherObject>

我有两个相同类型的列表

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

对于同一日期和同一用户的订单,我希望捕获匹配订单中的数量

我能够找到匹配的List<Orders>。但不确定如何捕获并转换为新类的List<DiffOrders>。你能帮忙吗

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

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

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


共 (3) 个答案

  1. # 1 楼答案

    听起来这个问题的症结在于,您想要省略current中任何在previous中没有匹配项的项,但是使用previous中的实际对应值转换中有匹配项的项。在这种情况下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());
    
  2. # 2 楼答案

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

    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;
    }
    
  3. # 3 楼答案

    据我所知,这个问题的一个主要需求是当前和之前Order的映射,这样您就可以根据细节构建MatchOrder。当然,这将需要一个map操作,以及filter在构建之前条目的电流的过程中

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