我有这个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 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:方法 - &gt; maxDepth不起作用。在该图像中,正确的最大深度为3(请参阅带圆圈的),但该方法给出的值为4。
问题2:根据maxDepth,我希望得到列表中的所有人。例如,如果我通过maxdept 3传递person对象,如果我将深度传递为2,我应该得到所有 person 1 和 person 2 和 NOT person 3 < / strong>在该图表的列表中。我通过编写该方法尝试了这项工作 - &gt; public static设置getPersonLevel(Person person,int depth),但这不起作用,因为它一直返回空集。
感谢任何帮助
答案 0 :(得分:2)
我修改了你的代码如下:
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 - &gt;人0
System.out.println(p0.maxDepth());
问题2的客户端代码: p0 - &gt;人0
Set<Person> ppl= new HashSet<>();
int depth = 2;
System.out.println(p0.getPersonLevel(p0, depth, ppl));
希望这会有所帮助。
答案 1 :(得分:2)
在你的方法中
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
也不会添加任何元件。
主要障碍是您显然不想包含/计算您正在评估/调用方法的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;
}
}