获取深度对象中的每个对象

Get each object within depth object

我有这个 Person 对象。每个人都有person object list等等,而且可以无限深入

    public class Person {

        private List<Person> people = new ArrayList<>();

        public Person() {
        }

        ...

        public List<Person> getPeople() {
            return people;
        }

        public void setPeople(List<Person> people) {
            this.people = people;
        }

        public int maxDepth() {
            int maxChildrenDepth = 0;
            for (Person prs: people) {
                maxChildrenDepth = Math.max(maxChildrenDepth, prs.maxDepth());
            }
            return 1 + maxChildrenDepth;
        }

        public static Set<Person> getPersonLevel(Person person, int depth) {
            Set<Person> ppl= new HashSet<>();
            if (depth > 0) {
                 person.getPeople().forEach(prs -> ppl.addAll(getPersonLevel(prs, depth - 1)));
    }
      return ppl;
    } 

问题 1:方法 --> maxDepth 不起作用。在该图像中,正确的最大深度为 3(请参见带圆圈的部分),但该方法给出的值为 4。

问题2:根据maxDepth,我想获取列表中的所有人。例如,如果我将 person 对象传递给 maxdept 3,如果我将 depth 作为 2 传递,我应该得到所有 person 1person 2NOT person 3 在该图表的列表中。我尝试通过编写该方法 --> public static Set getPersonLevel(Person person, int depth) 但这不起作用,因为它 return 空集每时每刻。

感谢任何帮助

我修改了你的代码如下:

public class Person {
        private List<Person> people = new ArrayList<>();
        private String name;
        public Person() {
        }
        public Person(String name) {
            this.name = name;
        }
        public List<Person> getPeople() {
            return people;
        }
        public void setPeople(List<Person> people) {
            this.people = people;
        }

        public int maxDepth() {
            if (people.isEmpty()) {
                return 0;
            }
            int maxChildrenDepth = 0;
            for (Person prs: people) {
                maxChildrenDepth = Math.max(maxChildrenDepth, prs.maxDepth());
            }
            return 1+maxChildrenDepth;
        }

       public static void getPersonLevel(Person person, int depth, Set<Person> ppl) {
            if (depth <= 0) {
                return;
            } else {
                for (Person prs : person.getPeople()) {
                    getPersonLevel(prs, depth - 1, ppl);
                }
            }
            ppl.addAll(person.getPeople());
       }

      //just for logging
       @Override
       public String toString() {
            return "Person [name=" + name + "]";
      }
}

问题 1 的客户代码:p0 -> 人员 0

System.out.println(p0.maxDepth());

问题2的客户端代码: p0 -> 人 0

Set<Person> ppl= new HashSet<>();
int depth = 2;
System.out.println(p0.getPersonLevel(p0, depth, ppl));

希望这会有所帮助。

用你的方法

    public int maxDepth() {
        int maxChildrenDepth = 0;
        for (Person prs: people) {
            maxChildrenDepth = Math.max(maxChildrenDepth, prs.maxDepth());
        }
        return 1 + maxChildrenDepth;
    }

很明显,单个 Person 对象,其列表中没有任何元素,已经 return 深度为 1(一)。所以每增加一个级别就会增加一个,在你的图片中,你有四个级别,所以你得到的结果是四个。

你的方法

public static Set<Person> getPersonLevel(Person person, int depth) {
    Set<Person> ppl= new HashSet<>();
    if (depth > 0) {
         person.getPeople().forEach(prs -> ppl.addAll(getPersonLevel(prs, depth - 1)));
    }
    return ppl;
}

正在遍历整个 Person 树,遍历所有级别,但在任何时候,它实际上都没有向 Set 添加任何元素。它所做的只是 addAll 使用此递归方法的另一个结果,但只要没有实际添加发生,结果就是一个空集并且将 addAll 与空集一起使用不会再次添加任何内容元素.

主要障碍是您显然不想include/count您evaluating/calling方法所在的Person实例。我建议直接将此行为设为可选,这样当遍历树时,您可以指示方法始终对子元素进行计数。然后,您可以提供其他方法,默认行为不计算根元素:

public class Person {
    private List<Person> people = new ArrayList<>();

    public Person() {
    }
    public List<Person> getPeople() {
        return people;
    }
    public void setPeople(List<Person> people) {
        this.people = people;
    }

    public Stream<Person> people() {
        return people.stream();
    }

    public Stream<Person> peopleLevel(int depth, boolean includeThis) {
        if(depth<0) throw new IllegalArgumentException();
        if(depth==0) return includeThis? Stream.of(this): Stream.empty();
        Stream<Person> sub = people();
        if(depth > 1) sub = sub.flatMap(p -> p.peopleLevel(depth-1, true));
        return includeThis? Stream.concat(Stream.of(this), sub): sub;
    }

    public static Set<Person> getPersonLevel(Person person, int depth) {
        return person.peopleLevel(depth, false).collect(Collectors.toSet());
    }

    public int maxDepth() {
        return maxDepth(false);
    }
    public int maxDepth(boolean includeThis) {
        int chDepth = people().mapToInt(p -> p.maxDepth(true)).max().orElse(0);
        if(includeThis) chDepth++;
        return chDepth;
    }
}