递归地遍历嵌套列表

0yg35tkg  于 2021-08-20  发布在  Java
关注(0)|答案(2)|浏览(304)

我想实现一个递归函数,它遍历列表中对象的子列表,并将子列表中的所有元素添加到一个大列表中。
我的目标如下:
使用名为.getdependson()的函数列出任务,该函数返回它所依赖的列表。
从一个任务开始,它依赖于任务b,然后又依赖于任务c和d,我想递归地迭代每个任务,并将它们添加到一个大列表中,其中包括任务a的每个依赖任务。

public List<Task> addDependencies(List<Task> tasks) {
  for (Task task: tasks) {
   if (!task.getDependsOn().isEmpty()) {
    tasks.addAll(addDependencies(task.getDependsOn()));
    return tasks;
   } else {
    return tasks;
   }
  }
  return tasks;
}

这是我尝试过的,但它不起作用,因为它抛出了invocationtargetexception。我正试图解决我的问题,试图在我的大脑中调试它,现在已经有2个小时了,但无法解决它。

dfty9e19

dfty9e191#

您的方法中存在一些问题:
你只要把钱还给我就行了 tasks 什么时候 task.getDependsOn() 是空的,忽略剩余的 task 独立,你应该打电话 continue 相反
你打电话的时候没有复印 addDependencies(task.getDependsOn()) ,这会产生意外的副作用(改变 task.getDependsOn() ).
对于这个问题,我更喜欢使用stream with flatmap,因为它不会产生副作用,并且我们不需要创建列表的多个副本。

public static Stream<Task> flattenDependencies(List<Task> tasks) {
    return tasks.stream().flatMap(task -> {
        Stream<Task> flattened = flattenDependencies(task.getDependsOn());
        return Stream.concat(Stream.of(task), flattened);
    });
}

完整示例
主类

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class FlattenTask {
    public static void main(String[] args) {
        Task a = new Task("a");
        Task b = new Task("b");
        Task c = new Task("c");
        Task d = new Task("d");
        Task e = new Task("e");
        Task f = new Task("f");
        a.setDependsOn(List.of(b, c));
        b.setDependsOn(List.of(d, e));
        List<Task> tasks = List.of(a, f);
        System.out.println(flattenDependencies(tasks).collect(Collectors.toList()).toString());
    }

    public static Stream<Task> flattenDependencies(List<Task> tasks) {
        return tasks.stream().flatMap(task -> {
            Stream<Task> flattened = flattenDependencies(task.getDependsOn());
            return Stream.concat(Stream.of(task), flattened);
        });
    }
}

任务

import java.util.Collections;
import java.util.List;

public class Task {

    private final String code;
    private List<Task> dependsOn = Collections.emptyList();

    public Task(String code) {
        this.code = code;
    }

    public List<Task> getDependsOn() {
        return dependsOn;
    }

    public void setDependsOn(List<Task> dependsOn) {
        this.dependsOn = dependsOn;
    }

    @Override
    public String toString() {
        return code;
    }
}
4smxwvx5

4smxwvx52#

我认为您的异常正在发生,因为您试图在迭代列表时同时追加列表。如果我明白你想做什么,也许像这样的事情会奏效

public List<Task> addDependencies(List<Task> tasks) {
  List<Task> subTaskList = new ArrayList<Task>;
  for (Task task: tasks) {
   if (!task.getDependsOn().isEmpty())
    subTaskList.addAll(addDependencies(task.getDependsOn()));
  }
  tasks.addAll(subTaskList);
  return tasks;
}

相关问题