无限递归嵌套对象

时间:2018-09-01 11:26:40

标签: 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和setters

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)

编辑: 解析器-从仙人掌解析项目/主机列表:

    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());
    }





}

我将使用递归方法将所有节点分组在corect位置,但是我遇到了相同的错误(使用stackoverflow),因此我不得不使用addToParent()函数进行处理。

1 个答案:

答案 0 :(得分:0)

当找到我节点的父节点时,我通过中断循环来管理它。我之所以这样做只是为了提高性能,因为即使找到父级,循环也要检查所有元素,所以我添加了break,它可以工作..不知道为什么。 下面的代码:

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);
    }
}