如何使用 Java 7 计算嵌套列表元素的大小?



我有一个对象,其中包含另一个对象的列表,其中包含另一个对象的列表等等......假设我想获取嵌套列表元素的数量(假设最后一个(,最好的方法应该是最好的方法,而不是像我在下面的示例中所做的那样在 java 中使用传统的 for 循环 -

public static void main(String[] args) {
Statement statement = new Statement();
statement.getInvAccount().add(new InvestmentAccount());
statement.getInvAccount().get(0).getSecAccountStmt().add(new SecurityStatement());
statement.getInvAccount().get(0).getSecAccountStmt().get(0).getTransactionStatement().add(new TransactionStatement());
statement.getInvAccount().get(0).getSecAccountStmt().get(0).getTransactionStatement().add(new TransactionStatement());
statement.getInvAccount().get(0).getSecAccountStmt().get(0).getTransactionStatement().add(new TransactionStatement());
// method to count the number of TransactionStatement
System.out.println("Size of TransactionStatement is : " + count(statement));
}
private static int count(Statement stmt) {
int countOfTransStmt = 0;
for (InvestmentAccount invAcc : stmt.getInvAccount()) {
if (invAcc != null) {
for (SecurityStatement secStmt : invAcc.getSecAccountStmt()) {
if (secStmt != null) {
countOfTransStmt = countOfTransStmt + secStmt.getTransactionStatement().size();
}
}
}
}
return countOfTransStmt;
}

在Java 7中,你不会比两个for循环做得更好。我不会打扰任何不同的事情。

在 Java 8 中,您可以使用流将其展平:

private static int count(Statement stmt) {
return stmt.getInvAccount().stream()
.filter(Objects::nonNull)
.flatMap(InvestmentAccount::getSecAccountStmt)
.filter(Objects::nonNull)
.flatMap(SecurityStatement::getTransactionStatement)
.count();
}

我鼓励你摆脱空检查。如果要忽略空值,最好首先不要插入它们。我希望它会在整个代码中消除许多额外的if检查。

我还鼓励你不要缩写你的变量和方法。拼出"声明"和"投资"等。缩写更难阅读,简洁并不是真正的胜利。

同样,尝试使用更具描述性的方法名称。countTransactions更适合主方法。对于各种getter,返回列表的方法应该是复数的:"getAccounts"而不是"getAccount"。请注意 getter 现在如何匹配类名;如果您知道类名,您就知道 getter 名称。您不必猜测其中一个是否缩写:

private static int countTransactions(Statement statement) {
return statement.getInvestmentAccounts().stream()
.flatMap(InvestmentAccount::getSecurityStatements)
.flatMap(SecurityStatement::getTransactionStatements)
.count();
}

递归在这种情况下可以工作: 大致思路如下:

private int countTransactions(object t)
{
int sum = 0;
if (t == null) return 0;
for (int i = 0; i < t.getAllSub().count; i++)
{
sum += countTransactions(t.subAt(i));
}
return sum;
}