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

标签 java recursion collections java-8 depth

我有这个 Person 对象。每个人都有person object的列表等等,而且可以是无限的

    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,我想获取列表中的所有人。例如,如果我传递最大深度为 3 的人对象,如果我传递深度为 2,我应该得到所有的人 1人 2不是人 3 在该图表的列表中。我尝试通过编写该方法 --> public static Set getPersonLevel(Person person, int depth) 但这不起作用,因为它始终返回空集。

感谢任何帮助

enter image description here

最佳答案

在你的方法中

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

很明显,单个 Person 对象(其列表中没有任何元素)将返回 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 set 再次不添加任何元素。

主要障碍是您显然不想包含/计算您正在评估/调用方法的 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;
    }
}

关于java - 获取深度对象中的每个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47740725/

相关文章:

java - 将集合反序列化为外部数组

ios - Collection View 还是 TableView ?

java - mongodb 连接被对等方重置 : socket writer error

java - 从 URL 读写图像

java - 二维递归

python - 向量化 numpy 折扣计算

java - EclipseRCP获取类所在的pluginId

java - 在java中将int分配给byte?

recursion - 拆分列表的 Lisp 递归

java - 如何检查 ArrayDeque 的索引是否为空?