在java中编写递归方法

时间:2011-05-08 21:27:12

标签: java recursion

我正在尝试编写一个递归方法,该方法搜索IData对象列表并返回特定实现。该列表包含实现接口IData的对象。

此接口有两种实现方式:

1)DataImpl

2)DataContainerImpl

DataContainerImpl有一个:

 List<IData> children;

所以它可以保存嵌套的DataContainerImpl元素或只是普通的DataImpl。这是我的工作:

  public static DataContainerImpl findDataContainerWithName(Collection<IData> elements, String name) {
    for (IData  element : elements) {
      if (element instanceof DataContainerImpl) {
        DataContainerImpl container = (DataContainerImpl) element;
        if (container.getName().equals(name)) {
          return container ;
        }

       container = findDataContainerWithName(container.getChildren(), name);
       if (container != null) {
         return container ;
       }
      }
    }
    return null;
  }

4 个答案:

答案 0 :(得分:5)

不完全确定你在这里做了什么,但是在它前面没有“返回”的情况下递归调用“findContainerByName()”对你没什么好处。

递归调用将返回,但随后调用将下降到底部并返回null。

例如,如果您的列表只包含1个DataContainerImpl,其名称与您调用方法的名称不匹配,但它包含一个只包含1个DataImpl的列表,您仍然会返回null。这是你想要的吗?

答案 1 :(得分:4)

坚持原始循环来处理列表,只有在找到DataContainerImpl时才会递归。

  public static DataContainerImpl findDataContainerWithName(Collection<IData> elements, String name) {
    for (IData element : elements) {
      if (element instanceof DataContainerImpl) {
        DataContainerImpl container = (DataContainerImpl) element;
        if (container.getName().equals(name)) {
          return container;
        }
        container = findDataContainerWithName(container.getChildren(), name);
        if (container) {
          return container;
        }
      }
    }
    return null;
  }

答案 2 :(得分:1)

我认为问题的根本原因在于您通过递归搜索列表中的相同元素。即这里

    // Call with remaining list...
    Collection<IData> copyAll = EcoreUtil.copyAll(elements);
    copyAll.remove(count);
    findDataContainerWithName(copyAll, name);

使用原始列表调用减去当前元素,而不仅仅是当前元素后的元素。因此,递归调用将不必要地一遍又一遍地检查相同的元素。特别是当你每次循环遍历列表时,这将是一个纯粹的递归方法是不必要的。

因此,如果您绝对想要使此搜索递归,则应仅检查第一个元素,然后将其从列表中删除,并使用其余列表递归调用。或者,如果您更喜欢在列表上循环,则在常见情况下(当元素不是DataContainerImpl时)不需要任何递归。这将是Java的做事方式,因为Java - 与函数式语言不同 - 对递归的支持有限。

答案 3 :(得分:1)

除了答案中已经提到的问题之外,您正在对列表中的每个元素进行递归调用,并传入所有其他元素。

因此,对于长度为N的列表,您将递归N-deep(不必要),从每个递归级别的列表中弹出一个元素。但是所有这些元素都可以在同一级别处理。

你是人为增加递归深度,因此你的StackOverflowError问题