在深层次结构中查找元素 - 迭代与递归

时间:2015-03-15 11:32:00

标签: java recursion iteration hierarchy circular-reference

我的菜单层次结构如下所示:

Root
    ProductGroups
        Products
            ItemTypes
                Items

我避免使用循环引用,因此只有从父级到其子级的引用,例如ProductGroup引用其产品。

如果我想知道项目所属的产品,我必须从Root开始遍历层次结构。这导致5个for循环:

for (MenuElement rootChild : Root.getChildren())
 for(ProductGroup group : rootChild.getChildren())
  for(Product product: group.getChildren())
   for(ItemType itemType : product.getChildren())
    for(Item item : itemType.getChildren())
     if(item == searchedItem)
      return product;

这是最好的方法还是您认为递归方法更好?

性能不应该是问题:10个产品组,10个产品,6个ItemTypes,~30个项目,因此递归方法不会导致大的过载。

递归的一个参数是较短的代码。在这个特定情况下还有更多吗?

2 个答案:

答案 0 :(得分:1)

如果你只是经常调用它,我建议在每个级别都包含一个父指针,或者如果你不想修改代码,为反向查找创建哈希图而不是使用任何一个你的解决方案。

Item->ItemType
ItemType->Product
Product->ProductGroup

您当前的解决方案始终遍历所有现有项目,这有点矫枉过正。如果你进行反向查找,你将在从一个hashmap获得2后完成,你的代码会更加简单:

type = itemToTypeMap.get(item);
if (null == type); //treat error
product = typeToProductMap.get(type);
if (null == product); //treat error
return product;

答案 1 :(得分:1)

我不知道递归方法是如何工作的,因为你在每个级别都有不同的类型,我们对这些类型或任何超类型等都知之甚少。

我可以给出的一条建议是关于耦合。

您的代码违反了Law of Demeter,因为此代码中的每个内部结构都存在高度耦合。这使得以后很难重构或扩展。

此代码更松散耦合:

for (MenuElement rootChild : Root.getChildren()) {
   Product product = rootChild.findProductByItem(searchedItem);
   if (product != null) return product;
}

然后在MenuElement

public Product findProductByItem(Item item) {
   for (ProductGroup group : getChildren()) {
     Product product = group.findProductByItem(item);
     if (product!=null) return product;
   }
   return null;
}

然后在ProductGroup

public Product findProductByItem(Item item) {
   for (Product product: getChildren())
     if (product.matchesItem(item))
        return product;
   return null;
}

然后在Product

public boolean matchesItem(Item item) {
   for (ItemType itemType : getChildren())
     if (itemType.matches(item))
       return true;
   return false;
}

然后在ItemType

public boolean matchesItem(Item searchItem) {
     for (Item item : getChildren())
       if (item == searchItem) //do you really mean == BTW?
         return true;
   return false;
}

现在你可以看到可能适合提升超类的重复模式,这可以帮助你实现递归代码。