【问题标题】:How to count the nested list elements size using Java 7?如何使用 Java 7 计算嵌套列表元素的大小?
【发布时间】:2019-02-28 03:44:03
【问题描述】:

我有一个对象,其中包含另一个对象的列表,其中包含另一个对象的列表等等...假设我想获取嵌套列表元素的计数(比如说最后一个),最好的方法应该是什么比我在下面的例子中使用传统的 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;
}

【问题讨论】:

  • 我会选择一种使用队列的 BFS 方法。通过这种方式,您可以获取可能的对象,并且在循环内部,您可以轻松找到它是否属于嵌套类型。让我知道数据示例以在此处给出任何代码示例。
  • 不妨看看访客模式。
  • @JohnKugelman 嵌套级别未知
  • @JohnKugelman 是的,如果嵌套级别更高,例如 6-7 怎么办?
  • @JohnKugelman OP 提到“我有一个对象,其中包含另一个对象的列表,其中包含另一个对象的列表,依此类推......

标签: java for-loop arraylist java-7


【解决方案1】:

在 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 更适合 main 方法。对于各种 getter,返回列表的方法应该是复数形式:“getAccounts”而不是“getAccount”。注意 getter 现在是如何匹配类名的;如果你知道类名,你就知道 getter 名。您不必猜测其中一个是否缩写:

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

【讨论】:

  • 谢谢约翰,我仍在使用 java 7,任何建议在 java 7 中执行此操作。也可能存在空值,因为我从其他无法控制的地方获取此信息。
  • 恕我直言,如果没有 Java 8+,您将无法逃脱循环。此外,如果您的代码有效,您的问题更适合code review
  • @Hars 请把 Java 7 的限制放在问题中,因为 Java 8 是标准,更不用说明天将是 Java 11 的正式版本。
  • @John :感谢方法命名建议,这只是这篇文章的一个简单示例,因此名称不准确。同样在真实数据中,我有 6 个嵌套列表,所以我将使用大约 5 个 for 循环,可以吗?
【解决方案2】:

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

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

【讨论】:

  • 这行不通。这些类有不同的方法来访问内部列表。
  • 用户可以更改方法或添加包装方法...
猜你喜欢
  • 2013-09-11
  • 2021-12-03
  • 2018-07-25
  • 2017-04-17
  • 2012-08-03
  • 1970-01-01
  • 2011-02-13
  • 1970-01-01
  • 2015-04-20
相关资源
最近更新 更多