java - 根据子值填充父 List 元素

标签 java list loops recursion arraylist

考虑以下代码:

AuditProgressReport:

public class AuditProgressReport
{
    private List<AuditProgressReport> audit_progress_reports = null;

    private String name = null;
    private String description = null;

    private int compliant;
    private int non_compliant;
    private int not_completed ;

    /**
     * 
     */
    public AuditProgressReport()
    {
        super();
    }

    public AuditProgressReport(
        String name_param,
        int compliant_param,
        int non_compliant_param,
        int not_completed_param)
    {
        super();

        this.name = name_param;
        this.compliant = compliant_param;
        this.non_compliant = non_compliant_param;
        this.not_completed = not_completed_param;
    }

    public void addToCompliant(int compl_to_add_param)
    {
        this.compliant += compl_to_add_param;
    }

    public void addToNonCompliant(int non_compl_to_add_param)
    {
        this.non_compliant += non_compl_to_add_param;
    }

    public void addToNotCompleted(int not_compl_param)
    {
        this.not_completed += not_compl_param;
    }

    public void setAuditProgressReports(List<AuditProgressReport> report_category_nodes_param)
    {
        this.audit_progress_reports = report_category_nodes_param;
    }

    public List<AuditProgressReport> getAuditProgressReports()
    {
        return this.audit_progress_reports;
    }

    public void setCompliant(int compliantParam)
    {
        this.compliant = compliantParam;
    }

    public int getCompliant()
    {
        return this.compliant;
    }

    public void setNonCompliant(int nonCompliantParam)
    {
        this.non_compliant = nonCompliantParam;
    }

    public int getNonCompliant()
    {
        return this.non_compliant;
    }

    public void setNotCompleted(int notCompletedParam)
    {
        this.not_completed = notCompletedParam;
    }

    public int getNotCompleted()
    {
        return this.not_completed;
    }

    public void setName(String name_param)
    {
        this.name = name_param;
    }

    public String getName()
    {
        return this.name;
    }

    public void setDescription(String description_param)
    {
        this.description = description_param;
    }

    public String getDescription()
    {
        return this.description;
    }

    @Override
    public String toString()
    {
        return ("Compliant["+this.compliant+
            "] Non-Compliant["+this.non_compliant+
            "] Not-Completed["+this.not_completed+"]");
    }
}

和 CLASS 测试员:

public class Tester
{
    public static void main(String[] args)
    {

        List<AuditProgressReport> main_level = new ArrayList<AuditProgressReport>();

        AuditProgressReport ar_1_1 = new AuditProgressReport("ar_1_1",0,0,0);
        AuditProgressReport ar_1_2 = new AuditProgressReport("ar_1_2",0,0,0);

        AuditProgressReport ar_1_1_1 = new AuditProgressReport("ar_1_1_1",0,0,0);
        AuditProgressReport ar_1_1_2 = new AuditProgressReport("ar_1_1_2",15,65,20);
        AuditProgressReport ar_1_1_3 = new AuditProgressReport("ar_1_1_3",20,30,50);

        AuditProgressReport ar_1_1_1_1 = new AuditProgressReport("ar_1_1_1_1",5,5,90);
        AuditProgressReport ar_1_1_1_2 = new AuditProgressReport("ar_1_1_1_2",55,5,40);
        AuditProgressReport ar_1_1_1_3 = new AuditProgressReport("ar_1_1_1_3",35,35,30);

        List<AuditProgressReport> arl_1_1_1 = new ArrayList<AuditProgressReport>();
        arl_1_1_1.add(ar_1_1_1_1);
        arl_1_1_1.add(ar_1_1_1_2);
        arl_1_1_1.add(ar_1_1_1_3);

        ar_1_1_1.setAuditProgressReports(arl_1_1_1);

        List<AuditProgressReport> arl_1_1 = new ArrayList<AuditProgressReport>();
        arl_1_1.add(ar_1_1_1);
        arl_1_1.add(ar_1_1_2);
        arl_1_1.add(ar_1_1_3);

        AuditProgressReport ar_1_2_1 = new AuditProgressReport("ar_1_2_1",10,30,60);
        AuditProgressReport ar_1_2_2 = new AuditProgressReport("ar_1_2_2",20,20,60);



        List<AuditProgressReport> arl_1_2 = new ArrayList<AuditProgressReport>();
        arl_1_2.add(ar_1_2_1);
        arl_1_2.add(ar_1_2_2);

        ar_1_1.setAuditProgressReports(arl_1_1);

        ar_1_2.setAuditProgressReports(arl_1_2);

        main_level.add(ar_1_1);
        main_level.add(ar_1_2);


        Tester tester = new Tester();

        for(AuditProgressReport prog_rep : main_level)
        {
            tester.populateParents(prog_rep, null);
        }

        //TODO Now check the values...
    }

    private void populateParents(
        AuditProgressReport audit_progress_param,
        AuditProgressReport parent_param)
    {
        List<AuditProgressReport> audit_progress = 
            audit_progress_param.getAuditProgressReports();

        System.out.println("name["+audit_progress_param.getName()+"]");

        if(parent_param != null)
        {
            int compl = audit_progress_param.getCompliant();
            int nonCompl = audit_progress_param.getNonCompliant();
            int notCompleted = audit_progress_param.getNotCompleted();

            parent_param.addToCompliant(compl);
            parent_param.addToNonCompliant(nonCompl);
            parent_param.addToNotCompleted(notCompleted);
        }

        if(audit_progress != null && ! audit_progress.isEmpty())
        {
            for(AuditProgressReport prog_rep : audit_progress)
            {
                this.populateParents(prog_rep,audit_progress_param);
            }
        }
    }
}

运行此命令时,您会注意到列表中父元素的值已更新为子列表中值的总和。

我面临的问题是我想让它在树中一直更新,而不仅仅是直接父级。

是否有一种模式可以帮助我实现这一目标?

见下图:

enter image description here

最佳答案

像其他人建议的那样,我会使用观察者模式。每个父节点监听子节点的变化。

但我的解决方案与@zmf 的解决方案不同,因为如果您有一棵包含很多子节点的大树,并且在每次更新时您都必须对每个值求和,那么您将花费大量处理时间。

如果每次更新子节点时只发送旧值和新值之间的差值会怎样?让我们举个例子。你从这棵树开始:

[12]--+--[10]-----[10]
      |
      +--[ 2]--+--[  ]
               |
               +--[ 2]

然后你像这样更新一个 child

[12]--+--[10]-----[10]
      |
      +--[ 2]--+--[ 3]
               |
               +--[ 2]

用值“3”更新的节点通过调用 parent.updateNode(3) 方法将其更改发送给父节点。父节点只需将其当前值(在此示例中为“2”)与其从子节点接收的值相加。所以它会更新为值“5”

[12]--+--[10]-----[10]
      |
      +--[ 5]--+--[ 3]
               |
               +--[ 2]

具有新值“5”的节点将调用parent.updateNode(3),最终解决方案将是

[15]--+--[10]-----[10]
      |
      +--[ 5]--+--[ 3]
               |
               +--[ 2]

恕我直言,这个解决方案更好,因为每个 updateNode() 方法只需将自己的当前值与从其子节点接收到的更改相加,并使用接收到的相同值调用其父节点。您不必从每个 child 那里获取值(value)并将所有值(value)相加。如果你有一棵大树,这会为你节省很多时间。因此,在此示例中,当您将值从 0 更改为 3 时。您将调用 2 次 parent.updateNode(3) 并且每个父节点都将得到更新。

关于java - 根据子值填充父 List 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9290352/

相关文章:

java - Spring继承特性

python - 如何使用可变长度序列的序列拆包?

c# - Sharepoint 2010 从模板创建列表

c - 如何删除某个范围内逗号分隔的素数中的最后一个逗号?

java - 如何在 Java 代码中连接来自不同数据库(MySql、Vertica)的两个表?

java - 无法使用 mailR 包通过 Outlook.com 发送电子邮件

java - 没有字段的类是否有特殊名称?

javascript - 在 Groovy 中等效于 Javascript 的 map()?

python - 逐行读取文件时出现名称未定义错误python

javascript - Div值增量javascript