Search code examples
javalistdeep-copy

Deep Copy of List element and recursion - java


I have a Trade class with 3 parameters (amount, description, date). The amount of each trade cannot be greater than maxAmount.

I have many trades saved in a ListToSend, and some of the amounts exceed the maxAmount limit, so I need to split those trades into multiple trades before sending the list.

I thought about working with two lists, my original ListToSend and a tradesToSplit list. Basically I want to:

  1. Move each splitableTrade from ListToSend to tradesToSplit.
  2. Then I want to loop over tradesToSplit and for every trade in there :
    • I call a recursiveMethod that is going to divide the amount by 2 and:
      • if amount/2 is not greater than maxAmount :
        • Then I create a newTrade, which is essentially a deep copy of the initial trade, and I set the newTrade amount to be originalAmount/2.
        • if not, I keep dividing the amount by calling recursiveMethod

But I'm stuck here as I have no idea how to edit the original trade after many iteration of recursiveMethod.

Is there a better way to achieve what I'm trying to do ?


Solution

  • in OOP it is recommended to keep objects immutable because immutable objects are inherently thread-safe, easier to debug (you can share the object reference without worrying about unexpected or unauthorized changes), etc.

    In your case I would create a function splitTrade that would take a trade of any amount and return a list of trade where each amount is less than maxAmount.

    Here is some pseudo java code:

    private List<Trade> splitTrade(Trade trade, List<Trade> acc) {
      if (trade.getAmount() > Trade.MAX_AMOUNT) {
        Trade trade1 = new Trade(Trade.MAX_AMOUNT, trade.getDescription(), trade.getDate());
        Trade trade2 = new Trade(trade.getAmount() - Trade.MAX_AMOUNT, trade.getDescription(), trade.getDate());
        acc.add(trade1);
        return splitTrade(trade2, acc);
      } else {
        acc.add(trade);
        return acc;
      }
    }
    
    public List<Trade> splitAllTrades(List<Trade> listToSend) {
      return listToSend.stream().flatMap((t) -> splitTrade(t, new ArrayList<Trade>()).stream().toList();
    }
    

    without the lambda syntax:

    public List<Trade> splitAllTrades(List<Trade> listToSend) {
      List<Trade> validTrades = new ArrayList<>();
      for (Trade trade: listToSend) {    
        validTrades.addAll(splitTrade(trade, new ArrayList<Trade>()));
      }
      return validTrades;
    }