java - 无限递归嵌套对象

标签 java json infinite-loop

在尝试将对象另存为 Json 时,我发现了一些关于无限循环的类似线程,但大多数都是关于 java + jpa 的,并且这些解决方案对我不起作用。我想创建一些数据的树结构。有类 ProjectNode 得到了

 private ArrayList<ProjectNode> children;

字段。我很确定这当然是问题所在,但它是这个结构中的主要领域,我不能忽视它。我已经测试过,我可以转换具有列表的对象和没有子节点的节点,但如果任何子节点在下面的代码中得到另一个子节点,则不能转换:

public class ProjectNode implements Comparable<ProjectNode>{
    private String parent;
    private String nodeName;
    private String nodeHref;
    private boolean hasChild;
    private int td;

    private ArrayList<ProjectNode> children;
    public ProjectNode() {
        super();
        // TODO Auto-generated constructor stub
    }

+ getter 和 setter

ObjectMapper objectMapper = new ObjectMapper();

        String json = objectMapper.writeValueAsString(parser.getProjectFactory().get(12));

parser.getProjectFactory() 返回 ParentNodes 列表(parent=null),我想转换 12 个元素,因为存在节点有子节点且该子节点有子节点的情况。导致此错误的原因:

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"]->java.util.ArrayList[31]->ProjectNode["children"])
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:734)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
    at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)
    at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)
    at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)

编辑: 解析器 - 从 cacti 解析项目/主机列表:

    public List<ProjectNode> getProjectFactory() throws FailingHttpStatusCodeException, MalformedURLException, IOException {    
    FileWriter fstream = new FileWriter("graphMap.txt");
    BufferedWriter out = new BufferedWriter(fstream);
    String [] hostInfo = null;
    HtmlTableCell cel= (HtmlTableCell) page.getHtmlPage().getByXPath("/html/body/table/tbody/tr[5]/td[1]").get(0);
    System.out.println(cel.getChildElementCount());
    List<HtmlDivision> divs = cel.getByXPath(".//div");
    System.out.println(divs.size());
    //checks if list of host has been added to the project
    ProjectTree projectTree = new ProjectTree();
    Map<Integer,String> suppMap = new HashMap<Integer,String>();
    for(HtmlDivision div : divs) {

        List<DomNode> td = div.getByXPath(".//table/tbody/tr/td");
        if(td.size()>2) {

            ProjectNode pn = new ProjectNode(getNameSrc(td).split("@")[0],getNameSrc(td).split("@")[1],td.size());  

        hostInfo = getNameSrc(td).split("@");   
                if(pn.getTd()>3) {                      

                    if(!suppMap.get(pn.getTd()-1).isEmpty()) {
                        pn.setParent(suppMap.get(pn.getTd()-1));
                    }
                    if(suppMap.get(pn.getTd())!=null){
                        suppMap.remove(pn.getTd());                         
                    }
                    suppMap.put(pn.getTd(), pn.getNodeName());
                    projectTree.addNodeToTree(pn);

                } else {

                    projectTree.addNodeToTree(pn);

                    suppMap.put(pn.getTd(), pn.getNodeName());
                //out.write(pn.toString()+"\n");
                }
        }
    }
    ArrayList<ProjectNode> pns = projectTree.getNodeList();
    Collections.sort(pns, Comparator.comparing(ProjectNode::getTd)); 
    Collections.reverse(pns);
    projectTree.setNodeList(pns);
    List<ProjectNode> finalList = new ArrayList<ProjectNode>();
    for(ProjectNode pn :pns ) {
        if(pn.getTd()==3) {
            finalList.add(pn);
        }else {             
            projectTree.addToParent(pn);            
        }
    }
    Collections.reverse(finalList);
for(ProjectNode pn : finalList) {
    Collections.sort(pn.getChildren());

}
out.write(finalList.get(12).getChildren().get(4).getChildren().toString());
out.close();

    System.out.println(finalList.size());



    return finalList;
}

ProjectTree 类

public class ProjectTree {
    private ProjectNode rootNode;

private ArrayList<ProjectNode> NodeList;

public ProjectTree() {
        super();
        this.NodeList = new ArrayList<ProjectNode>();

}
public ProjectTree(ProjectNode rootNode, ArrayList<ProjectNode> nodeList) {
    super();
    this.rootNode = rootNode;
    NodeList = nodeList;
}


public ArrayList<ProjectNode> groupHosts(){

    return this.NodeList;
}

public void addToParent(ProjectNode pn) {
    for(ProjectNode pnA :this.NodeList) {
        if(pnA.getNodeName().equals(pn.getParent())) {
            if(pnA.getChildren()!=null && pnA.getChildren().size()!=0) {
                pnA.sortChildren();
            }
            pnA.addChlild(pn);
        }

    }
}

public ProjectNode getRootNode() {
    return rootNode;
}
public void setRootNode(ProjectNode rootNode) {
    this.rootNode = rootNode;
}
public ArrayList<ProjectNode> getNodeList() {
    return NodeList;
}
public void setNodeList(ArrayList<ProjectNode> nodeList) {
    NodeList = nodeList;
}


}

ProjectNode.class

public class ProjectNode implements Comparable<ProjectNode>{
    private String parent;
    private String nodeName;
    private String nodeHref;
    private boolean hasChild;
    private int td;

    private ArrayList<ProjectNode> children;
    public ProjectNode() {
        super();
        // TODO Auto-generated constructor stub
    }
    public ProjectNode( String nodeName, String nodeHref, int td) {
        super();

        this.nodeName = nodeName;
        this.nodeHref = nodeHref;
        this.hasChild =false;
        this.td=td;
    }
    public void addChlild(ProjectNode pn) {
        if(children!=null) {
            this.children.add(pn);
        }else {
            this.children = new ArrayList<ProjectNode>();
            this.children.add(pn);
        }
    }

    public List<ProjectNode> getChildren() {
        return children;
    }
    public void sortChildren() {
            Collections.sort(this.getChildren());;
        //Collections.sort(this.getChildren(), Comparator.comparing(ProjectNode::getNodeName)); 
            //System.out.println(this.children.toString());


    }
    public void setChildren(ArrayList<ProjectNode> children) {
        this.children = children;
    }
    public int getTd() {
        return td;
    }
    public void setTd(int td) {
        this.td = td;
    }
    public boolean isHasChild() {
        return hasChild;
    }
    public void setHasChild(boolean hasChild) {
        this.hasChild = hasChild;
    }
    public String getParent() {
        return parent;
    }
    public void setParent(String parent) {
        this.parent = parent;
    }
    public String getNodeName() {
        return nodeName;
    }
    public void setNodeName(String nodeName) {
        this.nodeName = nodeName;
    }
    public String getNodeHref() {
        return nodeHref;
    }
    public void setNodeHref(String nodeHref) {
        this.nodeHref = nodeHref;
    }
    @Override
    public String toString() {
        return "ProjectNode [parent=" + parent + ", nodeName=" + nodeName + ", nodeHref=" + nodeHref + ", hasChild="
                + hasChild + ", td=" + td + ", children="  +"]";
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((children == null) ? 0 : children.hashCode());
        result = prime * result + (hasChild ? 1231 : 1237);
        result = prime * result + ((nodeHref == null) ? 0 : nodeHref.hashCode());
        result = prime * result + ((nodeName == null) ? 0 : nodeName.hashCode());
        result = prime * result + ((parent == null) ? 0 : parent.hashCode());
        result = prime * result + td;
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ProjectNode other = (ProjectNode) obj;
        if (children == null) {
            if (other.children != null)
                return false;
        } else if (!children.equals(other.children))
            return false;
        if (hasChild != other.hasChild)
            return false;
        if (nodeHref == null) {
            if (other.nodeHref != null)
                return false;
        } else if (!nodeHref.equals(other.nodeHref))
            return false;
        if (nodeName == null) {
            if (other.nodeName != null)
                return false;
        } else if (!nodeName.equals(other.nodeName))
            return false;
        if (parent == null) {
            if (other.parent != null)
                return false;
        } else if (!parent.equals(other.parent))
            return false;
        if (td != other.td)
            return false;
        return true;
    }
    @Override
    public int compareTo(ProjectNode o) {
        // TODO Auto-generated method stub
        return nodeName.compareTo(o.getNodeName());
    }





}

我会使用递归将所有节点分组到正确的位置,但我遇到了相同的错误(使用 stackoverflow),因此我必须使用 addToParent() 函数来解决问题。

最佳答案

当找到我的节点的父节点时,我通过中断循环来管理它。我这样做只是为了性能,因为即使在找到父级之前,循环也会检查所有元素,所以我添加了中断,并且它起作用了..不知道为什么.. 代码如下:

public void group() {

    int td = this.highestTd;
    while (td > 2) {

        List<ProjectNode> toRemove = new ArrayList<ProjectNode>();
        for (ProjectNode pnA : this.NodeList) {
            if(pnA.getTd()==3) {
                pnA.setParent("root");

            }
            if (pnA.getTd() == td) {

                for (ProjectNode pnB : this.NodeList) {
                    System.out.println(pnB.toString());

                    if (pnA.getParent()!=null && pnA.getParent().equals(pnB.getNodeName())) {

                        System.out.println("Dodaje "+pnA.getNodeName() + " Do "+pnB.getNodeName());
                        pnB.addChlild(pnA);

                        toRemove.add(pnA);
                        break;


                    }

                }

            }

        }
        td--;
        this.NodeList.removeAll(toRemove);
    }
}

关于java - 无限递归嵌套对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52127647/

相关文章:

C++ continue 语句导致无限循环

python - 跳出死循环

python - while循环不在python中退出

java - 当我的响应类型是 ModelAndView 时,如何向客户端发送 cookie?

java - jmxagent 在添加到 Camel 上下文中时抛出 saxparse 异常

Java正则表达式捕获特定字符串后的字符串

javascript - 迭代 django 模板中的 json 元素

python - 将多嵌套的 dict/json 加载到 pandas 中

java - 其他布局中的项目不响应用户事件

python - 对 Zoho Creator 返回的数据使用 json.loads() - extra_data() 错误