简体   繁体   中英

Convert to List<AnotherObject> from List<Object>,List<Object> using streams Java 8

I have 2 List of the same type say

class Orders {
    Strig User;
    String tradeDate;
    BigDecimal Qty;
}

and after comparison, I want to convert to list of another object say

class DiffOrders {
        String User;
        String tradeDate;
        BigDecimal currentQty;
        BigDecimal prevQty;
    }

I have two lists of Orders

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

   List<Orders> DiffOrders = current.stream()
                                       .filter(curr->previous.stream().anyMatch(prev->OrderPredicate.orderDiffSize(curr, prev)))
                                       .collect(Collectors.toList());

For orders on the same date and for the same user I want to capture the quantity in the matching order.

I am able to find the List<Orders> that matched. But not sure how to capture and convert to the List<DiffOrders> of new Class. Could you please help?

edit 1: OrderPredicate.orderDiffSize is a simple function that compares the user, trade date, quantity, and sign (+ for sell, - for buy) for the current and previous order. Not provided here for brevity.

edit 2: The size of the prev/current list is reasonable and can ignore o log n computation issues.

edit 3: Removed direction to keep it simple. For eg, I have orders in prevOrders and CurrentOrders on 01-Jul, 02-Jul, 03-Jul respectively. If the order quantity is different for the same date I want to put it in DiffOrders with quantity from current and previous. Hope this makes it clear.

One of the primary need from the question as I understand is the mapping of current and previous Order , so that you can construct the MatchOrder out of the details. Ofcourse, this will require a map operation along with the filter during the construction of the such current to previous entries.

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

Sounds like the crux of this problem is that you want to omit any items in current that don't have matches in previous , but transform items that do have matches using the actual corresponding value from previous . In that case flatMap is what you want. You can use flatMap to transform each Order not into a DiffOrders , but into a stream of DiffOrders that will be empty for non-matches and consist of a single element for matches.

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

for simple code and easy algorithm in two steps it can be resolved;

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM