使用Java 8流从List <Object>,List <Object>转换为List <AnotherObject>

时间:2019-07-29 12:54:16

标签: java java-8 mapping java-stream

我有2个相同类型的列表

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: OrderPredicate.orderDiffSize是一个比较简单的函数 当前和先前订单的用户,交易日期,数量和符号(+表示出售,-表示购买)。为简洁起见,此处未提供。

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

编辑3: 删除了方向以保持简单。 例如,我分别在7月1日,7月2日,7月3日的prevOrders和CurrentOrders中拥有订单。如果同一天的订单数量不同,我想将其放入DiffOrders中,数量与当前和之前的数量相同。希望这可以弄清楚。

3 个答案:

答案 0 :(得分:1)

据我所知,该问题的主要需求之一是当前Order与先前MatchOrder的映射,以便您可以从细节中构造map。当然,在将这种当前构造为先前条目时,将需要filterList<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()); 一起进行操作。

var oldStr: String = "kotlin"
var firstChar: String = oldStr.elementAt(0).toString()
Log.d("firstChar", firstChar.toString())

答案 1 :(得分:1)

听起来像是这个问题的症结所在,是您要忽略current中没有匹配项的所有previous项目,而要转换要做具有的项目使用previous中的实际对应值进行匹配。在这种情况下,flatMap是您想要的。您可以使用flatMap将每个Order转换为DiffOrders stream ,而不是将它们转换为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 :(得分:0)

对于简单的代码和简单的算法,只需两个步骤即可解决;

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;
}