英文:
Deep Copy of List element and recursion - java
问题
我有一个名为Trade
的类,有三个参数(amount
,description
,date
)。每笔交易的amount
不能大于maxAmount
。
我有很多交易保存在ListToSend
中,其中一些金额超过了maxAmount
限制,所以我需要在发送列表之前将这些交易拆分成多个交易。
我考虑使用两个列表,原始的ListToSend
和一个名为tradesToSplit
的列表。
基本上我想要:
- 将
ListToSend
中的每个可拆分交易移动到tradesToSplit
中。 - 然后我想循环遍历
tradesToSplit
,对其中的每笔交易进行以下操作:- 调用一个名为
recursiveMethod
的方法,该方法将金额除以2,并且:- 如果
amount/2
不大于maxAmount
:- 然后我创建一个
newTrade
,它实质上是原始交易的深拷贝,然后将newTrade
的金额设置为originalAmount/2
。 - 否则,继续通过调用
recursiveMethod
来继续分割金额。
- 然后我创建一个
- 如果
- 调用一个名为
但是我卡在这里,因为我不知道如何在多次调用recursiveMethod
后编辑原始交易。
有没有更好的方法来实现我想做的事情?
英文:
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:
- Move each
splitableTrade
fromListToSend
totradesToSplit
. - 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 thanmaxAmount
:- Then I create a
newTrade
, which is essentially a deep copy of the initial trade, and I set thenewTrade
amount to beoriginalAmount/2
. - if not, I keep dividing the amount by calling
recursiveMethod
- Then I create a
- if
- I call a
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 ?
答案1
得分: 2
在面向对象编程中,建议将对象保持为不可变,因为不可变对象天生是线程安全的,更容易调试(您可以共享对象引用而不必担心意外或未授权的更改),等等。
对于你的情况,我建议创建一个名为splitTrade
的函数,它会接受一个任意amount
的交易,并返回一个交易列表,其中每个amount
都小于maxAmount
。
以下是一些伪Java代码:
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();
}
不使用lambda语法的版本:
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;
}
英文:
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;
}
答案2
得分: 1
潜在的解决方案是在Trade
类内部创建一个生成符合条件的交易流的方法:
public class Trade {
...
public Stream<Trade> streamLegalTrades() {
if (amount < maxAmount)
return Stream.of(this);
Trade halfTrade = new Trade(amount / 2, ...);
return Stream.of(halfTrade, halfTrade)
.flatMap(Trade::streamLegalTrades);
}
}
如果你对流不熟悉,上述语句可能有点令人困惑。但它基本上会生成2个新交易,然后为每个交易生成一个合法交易流。
然后,这使得将交易列表转换为所需格式变得很简单:
tradeList.stream().flatMap(Trade::streamLegalTrades).toList();
英文:
A potential solution would be to have a method inside Trade
that generates a stream of trades that satisfy the criteria:
public class Trade {
...
public Stream<Trade> streamLegalTrades() {
if (amount < maxAmount)
return Stream.of(this);
Trade halfTrade = new Trade(amount / 2, ...);
return Stream.of(halfTrade, halfTrade)
.flatMap(Trade::streamLegalTrades);
}
}
If you're not familiar with streams then that statement might be a bit confusing. But it essentially produces 2 new trades and then produces a stream of legal trades for each of those.
This then makes it trivial to convert your list of trades:
tradeList.stream().flatMap(Trade::streamLegalTrades).toList();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论