我阅读了有关java recorsion的文档,我认为我已经理解了它,但是当我尝试在下面的示例中使用它时,它无法按预期工作。
我是一个班级account
,有amount
,可以有更多的子帐户。我会实现一个方法getSum
,它必须返回帐户金额和所有子帐户金额的总和。在下面的代码中,方法getSumm()
的调用应该返回550,但它表现得很奇怪。有人可以帮忙吗?
public class Balance{
ArrayList<Balance> subAccounts = new ArrayList<Balance>();
String accountID = null;
Double amount = null;
double result=0;
public double getSum(ArrayList<Balance> subAccounts){
if(subAccounts !=null && subAccounts.size()>0){
for (int i = 0; i < subAccounts.size(); i++) {
result = result + getSum(subAccounts.get(i).subAccounts);
}
}
else {
return amount;
}
return result;
}
public static void main(String[] args) {
Balance bs1 = new Balance();
Balance bs2 = new Balance();
Balance bs3 = new Balance();
bs1.amount=100.0;
bs2.amount=150.0;
bs3.amount=300.0;
ArrayList<Balance> subAccounts1 = new ArrayList<Balance>();
bs2.subAccounts=null;
bs3.subAccounts=null;
subAccounts1.add(bs2);
subAccounts1.add(bs3);
bs1.subAccounts=subAccounts1;
double sum= bs1.getSum(subAccounts1);
System.out.println(sum);
}
}
答案 0 :(得分:5)
你没有正确封装使事情变得复杂。这意味着您必须将正确的参数传递给getSum(...)
,并且因为您可能会传入错误的参数,所以缺少封装与错误参数的结合确保了错误的答案。
关键是要停止要求 来电者需要了解getSum(...)
的工作原理。帐户应该能够在没有帮助的情况下计算自己的金额。毕竟,一个帐户应该已经有了类中的数据,那么为什么还需要其他人告诉它数据呢?
public class Account {
// A list of subAccounts, each which
// is responsible for its own value.
private List<Account> subAccounts;
// value in this account, not assigned
// to subAccounts
private double value;
public double getSum() {
double sum = this.value;
for (Account account : subAccounts) {
sum += account.getSum();
}
return sum;
}
}
答案 1 :(得分:2)
getSum的终止条件之一是
return amount;
其中 amount 是一个类范围的变量。这可能不是你想要的。您可能应该返回结果。
此外,结果被定义为类范围的变量。它应该是getSum的本地。
答案 2 :(得分:2)
你的逻辑有点不确定。
getSum不应该接受参数,因为subAccounts成员变量已经是对象的一部分。
您还在成员变量中收集内部总和。使用局部变量来避免问题。
每个人都已经说过...确保你实际上并没有使用递归。这只是一个如何使用recusion的演示,这样就可以了。
以下是更正后的计划:
import java.util.ArrayList;
public class Balance {
ArrayList<Balance> subAccounts = new ArrayList<Balance>();
String accountID = null;
Double amount = null;
public double getSum() {
if (subAccounts != null) {
Double sum = 0.0;
for (int i = 0; i < subAccounts.size(); i++) {
sum += subAccounts.get(i).getSum();
}
return amount + sum;
} else {
return amount;
}
}
public static void main(String[] args) {
Balance bs1 = new Balance();
Balance bs2 = new Balance();
Balance bs3 = new Balance();
bs1.amount = 100.0;
bs2.amount = 150.0;
bs3.amount = 300.0;
ArrayList<Balance> subAccounts1 = new ArrayList<Balance>();
bs2.subAccounts = null;
bs3.subAccounts = null;
subAccounts1.add(bs2);
subAccounts1.add(bs3);
bs1.subAccounts = subAccounts1;
double sum = bs1.getSum();
System.out.println(sum);
}
}
答案 3 :(得分:1)
这是一个更简单,更安全的工作方式:
public double getSum(){
double result = this.amount;
if(this.subAccounts !=null){
for (Balance subAccount : this.subAccounts) {
result = result + subAccount.getSum();
}
}
return result;
}
您可以简单地称呼它:bs1.getSum()
。这个想法很简单直观:总和是所有子账户金额+总和的数量。
答案 4 :(得分:0)
请参阅尼古拉斯的回答以获得更完整的答案
尝试
double sum= bs1.getSum(bs1);
这不直观..但会给你你想要的答案。你应该稍微重构你的getSum()以获得直观的功能。
此外,您需要将最后一次返回更改为:
return result + amount;