简体   繁体   English

递归检索列表中的所有元素

[英]Retrieving recursively all elements in a list

I have a class "Job" defined like this : 我有一个像这样定义的“工作”类:

public class Job extends AbstractJob
{
    private String name;
    private String jobCount;
    private String status;
    private List<Job> children;


    public Job(String name, String jobCount, String status, List<Job> children) {
        this.name = name;
        this.jobCount = jobCount;
        this.status = status;
        this.children = children;
    }

    public String getName()
    {
        return name;
    }

    public String getJobCount()
    {
        return jobCount;
    }

    public String getStatus()
    {
        return status;
    }

    public List<Job> getChildren() {
        return children;
    }

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

    public void setJobCount(String jobCount) {
        this.jobCount = jobCount;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public void setChildren(List<Job> children) {
        this.children = children;
    }
}

What I would like to do is to be able to retrieve all the elements in a list of jobs including their children as well. 我想做的是能够检索工作列表中的所有元素,包括他们的孩子。 Here's what I have done so far: 到目前为止,这是我所做的:

   public List<Job> getJobChildren(Job job) {

        List<Job> result = new ArrayList<Job>();
        if (job == null) {
            return new ArrayList<Job>();
        }
        List<Job> children = job.getChildren();
            for (Job k : children) {
                if (children != null && !children.isEmpty()) {
                    result.addAll(children);
                    getJobChildren(k);
                } else {
                    result.add(k);
                }
            }
            return result;
    }

In the main class, I instantiated and populated so jobs to test it, but I get a nullpointerException: 在主类中,我实例化并填充了作业,以便对其进行测试,但是却得到nullpointerException:

Job job2 = new Job("JOB0002","0002","Finished",null);
Job job3 = new Job("JOB0003","0003","Error",jobSubList);
Job job4 = new Job("JOB0004","0004","En cours",null);
jobSubList.add(job4);
List<Job> jobList = new ArrayList<Job>();
jobList.add(job2);
jobList.add(job3);
Job job = new Job("JOB0001","0001","En Cours",jobList);

I know why I'm getting the exception, but I'm not able to edit the method to make it return all the children. 我知道为什么会收到异常,但是我无法编辑该方法以使其返回所有子级。

The idea is to go through all the jobs and see if them too have jobs of their own. 想法是遍历所有工作,看看他们是否也拥有自己的工作。 If they do, I go a level deeper and retrieve all those children, and I keep doing this until I retrieve all the jobs. 如果他们愿意,我会更深入并检索所有这些孩子,直到我找到所有工作之前,我都会继续这样做。

Could you please tell me what am I doing wrong in that method? 您能告诉我该方法做错了什么吗?

Thank you. 谢谢。

The NullPointerException because you are making the null check of the children list after the for loop starts. NullPointerException因为在for循环启动后children列表进行了空检查。 It should be done before entering the loop. 应该进入循环之前完成。 Also, I notice that you do not aggregate the results, upon every call of the getJobChildren() you instantiate a new list and you are not adding it to the parent call when the method returns. 另外,我注意到您没有汇总结果,在每次调用getJobChildren()都实例化一个新列表,并且在方法返回时没有将其添加到父调用中。

A depth-first recursive algorithm for traversing the children list (assuming no cycles) could be as follows: 用于遍历子级列表的深度优先递归算法(假设没有循环)可以如下:

public List<Job> getJobChildren(final Job job, final List<Job> result) {
    if (job == null) {
        return result;
    }

    result.add(job);
    if(job.getChildren() != null){
        for(Job current : job.getChildren()){
            getJobChildren(current, result);
        }
    }

    return result;
}

You will need to trigger the first call using a new ArrayList to collect the results. 您将需要使用新的ArrayList触发第一次调用以收集结果。

List<Job> results = new ArrayList<>();
getJobChildren(parentJob, results);

// Use the results here.

You need to check for null: 您需要检查是否为空:

    if (job.getChildren() != null) {
        for (Job k : children) {

job.getChildren() could be null. job.getChildren()可以为null。 No need for iterating a null list. 无需迭代空列表。

Corrected method: 更正的方法:

public static List<Job> getJobChildren(Job job) {

    List<Job> result = new ArrayList<Job>();
    if (job == null) {
        return new ArrayList<Job>();
    }
    List<Job> children = job.getChildren();
    if (job.getChildren() != null) {
        for (Job k : children) {
            if (children != null && !children.isEmpty()) {
                result.addAll(children);
                getJobChildren(k);
            } else {
                result.add(k);
            }
        }
    }
    return result;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM