Java:递归地迭代映射
我们有一个看起来像“递归”数据结构的对象 假设有一个Person对象,其结构如下Java:递归地迭代映射,java,algorithm,recursion,Java,Algorithm,Recursion,我们有一个看起来像“递归”数据结构的对象 假设有一个Person对象,其结构如下 public class Person { private String id; private Map<String,Person> persons; public Person(String id, Map<String,Person> persons){ this.id = id; this.persons = persons
public class Person {
private String id;
private Map<String,Person> persons;
public Person(String id, Map<String,Person> persons){
this.id = id;
this.persons = persons;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Map<String, Person> getPersons() {
return persons;
}
public void setPersons(Map<String, Person> persons) {
this.persons = persons;
}
@Override
public String toString() {
return "Person [id=" + id + ", persons=" + persons + "]";
}
}
注1:ImmutableMap
来自google guava collection
注2:假设Person对象中映射的“键”是Person的名称
给定此人的姓名,迭代并获取id的最有效方法是什么。
例如,如果输入是“EVE”,那么输出应该是Ne'Y01'
因为您已经使用番石榴,请考虑将这样的方法添加到<代码>人< /代码>类:
public FluentIterable<Map.Entry<String, Person>> tree() {
if (persons == null)
return FluentIterable.from(ImmutableList.of());
return FluentIterable.from(persons.entrySet())
.transformAndConcat(
entry -> Iterables.concat(ImmutableList.of(entry), entry.getValue().tree()));
}
或者使用fluentiable
操作:
System.out.println(p1.tree()
.firstMatch(e -> e.getValue().getId().equals(name))
.get().getKey());
你的结构实际上是一种树。因此,您可以使用排序树的标准方法。如果您的树是一个二叉树(看起来不是),您可能能够非常有效地实现这一点 下面的方法行得通,但我没有证据证明它是最有效的方法。非二叉树大多只需要插入 效率取决于您认为递归性的堆叠程度。如果您认为大多数结构与示例结构相似,即:非常深,但每个级别只有几个人,这将非常有效。特别是如果你的结果接近底部
public String iterate(String name) {
if (persons != null) {
for (Entry<String, Person> entry : persons.entrySet()) {
Person value = entry.getValue();
if (value.getId().equals(name)) {
return entry.getKey(); //Since the key of each map is the ID when they return the key
} else {
String ans = value.iterate(name);
if (ans != null) {
return ans;
}
}
}
}
return null;
}
公共字符串迭代(字符串名称){
如果(人!=null){
for(条目:persons.entrySet()){
Person value=entry.getValue();
if(value.getId().equals(name)){
return entry.getKey();//因为每个映射的键都是返回键时的ID
}否则{
字符串ans=value.iterate(名称);
如果(ans!=null){
返回ans;
}
}
}
}
返回null;
}
它可以快速浏览整个人员列表堆栈,而无需返回顶部
但是,如果您有一个广泛的设置,并且您认为您的值将大部分接近顶部,那么您可以使用以下内容
public String iterate(String name) {
if (persons != null) {
for (Entry<String, Person> entry : persons.entrySet()) {
Person value = entry.getValue();
if (value.getId().equals(name)) {
return entry.getKey(); //Since the key of each map is the ID when they return the key
}
}
for (Entry<String, Person> entry : persons.entrySet()) {
String ans = entry.getValue().iterate(name);
if (ans != null) {
return ans;
}
}
}
return null;
}
公共字符串迭代(字符串名称){
如果(人!=null){
for(条目:persons.entrySet()){
Person value=entry.getValue();
if(value.getId().equals(name)){
return entry.getKey();//因为每个映射的键都是返回键时的ID
}
}
for(条目:persons.entrySet()){
字符串ans=entry.getValue().iterate(名称);
如果(ans!=null){
返回ans;
}
}
}
返回null;
}
这将允许快速找到结构顶部附近的东西,但在结构底部找到人的速度较慢
我猜你会想要更高的解决方案,它更标准。然而,我不认为他们之间有很大的区别。有关它的另一个版本,请参阅关于遍历树。这对于番石榴的
树遍历者来说是一个完美的工作:
Iterable<Person> allPersons = new TreeTraverser<Person>() {
@Override public Iterable<Person> children(Person p) {
return p.getPersons().values();
}
}.preOrderTraversal(rootPerson);
for (Person p : allPersons) {
if (p.getId().equals(id)) {
return p;
}
}
Iterable allPersons=new TreeTraverser(){
@覆盖公共Iterable子项(人员p){
返回p.getPersons().values();
}
}.preOrderTraversal(rootPerson);
对于(人员p:所有人员){
if(p.getId().equals(id)){
返回p;
}
}
你可以让人们在他们的人
地图中直接或间接地出现循环吗?到目前为止你做了什么?你知道TreeTraverser
已经为你做了大部分工作了吗?@LouisWasserman,别担心,我已经高估了你的答案:-)它比我的答案短不了多少,但事实上,使用专用功能更好。但是请注意,OP实际上也需要输入键,所以您的答案实际上并不能解决他的问题。也许你应该编辑它。
public String iterate(String name) {
if (persons != null) {
for (Entry<String, Person> entry : persons.entrySet()) {
Person value = entry.getValue();
if (value.getId().equals(name)) {
return entry.getKey(); //Since the key of each map is the ID when they return the key
} else {
String ans = value.iterate(name);
if (ans != null) {
return ans;
}
}
}
}
return null;
}
public String iterate(String name) {
if (persons != null) {
for (Entry<String, Person> entry : persons.entrySet()) {
Person value = entry.getValue();
if (value.getId().equals(name)) {
return entry.getKey(); //Since the key of each map is the ID when they return the key
}
}
for (Entry<String, Person> entry : persons.entrySet()) {
String ans = entry.getValue().iterate(name);
if (ans != null) {
return ans;
}
}
}
return null;
}
Iterable<Person> allPersons = new TreeTraverser<Person>() {
@Override public Iterable<Person> children(Person p) {
return p.getPersons().values();
}
}.preOrderTraversal(rootPerson);
for (Person p : allPersons) {
if (p.getId().equals(id)) {
return p;
}
}