在满足特定条件时停止递归方法

时间:2017-11-29 15:23:57

标签: java

我有一个名为Item的课程,其定义如下:

public class Item {
  private Long id;
  private String text;
}

它的DTO如下:

public class ItemDTO {
  private String id;
  private String text;
  private List<ItemDTO> children;
}

因此,使用DAO函数,我将从数据库中检索使用它的id对象,如下所示:

List<Item> children = itemDAO.findChildrenForItem(id);

对于每个孩子,我会检索它的孩子等等......为此,我创建了一个递归函数,在这种情况下起作用:

public List<ItemDTO> process(Long id) {
    List<ItemDTO> list = new ArrayList<>();

    // Get children
    List<Item> children = itemDAO.findChildrenForItem(id);

    if (children != null && children.size() > 0) {
      for (Item child : children) {
        ItemDTO dto = new ItemDTO();
        dto.setId(String.valueOf(child.getId()));
        dto.setText(child.getLib());
        dto.setChildren(process(child.getId()));
        list.add(dto);
      }
    }

    return list;
  }

我想要做的是当我在递归方法中达到第5次迭代时停止并移动到children数组中的下一个元素。

所以第一级孩子会有4个孩子,第二级孩子会有3个孩子等等......所以这就是我试过的:

public List<ItemDTO> process(Long id, Integer level) {
    List<ItemDTO> list = new ArrayList<>();

    // Get children
    List<Item> children = itemDAO.findChildrenForItem(id);

    if (children != null && children.size() > 0) {
      for (Item child : children) {
        level = level != null ? level : 0;
        ItemDTO dto = new ItemDTO();
        dto.setId(String.valueOf(child.getId()));
        dto.setText(child.getLib());
        level++;
        dto.setChildren(level <= 4 ? process(child.getId(), level) : null);
        list.add(dto);
        level = 0;
      }
    }

    return list;
  }

但是这并不起作用我总是让孩子比第四级更多。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

您永远不会检查 level的值,看看它是否已达到您的目标。您似乎也过度复杂地使用了level变量。考虑这样的结构:

public List<ItemDTO> process(Long id, Integer level) {
    List<ItemDTO> list = new ArrayList<>();

    // check the recursive logic's terminating condition
    if (level == 5) {
        // reached the intended bottom, return
        return list;
    }

    List<Item> children = itemDAO.findChildrenForItem(id);
    if (children != null && children.size() > 0) {
        for (Item child : children) {
            level = level != null ? level : 0;
            ItemDTO dto = new ItemDTO();
            dto.setId(String.valueOf(child.getId()));
            dto.setText(child.getLib());

            // you don't need a lot of logic here, just increment the level in the recursive call
            dto.setChildren(process(child.getId(), level + 1));

            list.add(dto);
        }
    }

    return list;
}

因此,当达到目标“级别”时,该方法不会找到子项并只返回一个空列表。 (或者您可以返回null或其他内容,这取决于您。)然后在递归到下一个“级别”时,您需要做的就是将1添加到当前“级别”。

基本上看起来你试图拥有一个全局变量,它知道递归的完整状态,并且基本逻辑关闭。相反,让递归方法本身只知道何时根据传递给它的值来停止。并且每次都只传递修改后的值。