解决循环引用导致的解析过程死循环

什么是循环引用

循环引用(Cyclic Reference)是指在数据结构(如对象、类或模块)中,两个或多个元素相互引用,形成一个闭环。

带来的问题

这种情况在编程中可能导致内存泄漏、解析过程无限循环或其他问题

解析过程触发无限循环

    public void bug(){
        // 数据 mock
        Node node = mock();
        // 解析触发死循环
        Parsed parse = parse(node);
    }

    private Node mock() {
        Node node = new Node();
        Node node1 = new Node();
        node.value = node1;
        node.name = "node";
        node1.value = node;
        node1.name = "node1";
        return node;
    }

    class Node {
        Node value;
        String name;
    }

    class Parsed {
        Parsed value;
        String name;
    }


    private Parsed parse(Node node) {
        int i = node.hashCode();
        Parsed result = new Parsed();
        result.value = parse(node.value);
        result.name = node.name;
        return result;
    }

解决方案

    public void test(){
        // 数据 mock
        Node node = mock();
        // 解析
        Parsed parse = parse(node, new HashMap<>());
    }

    private Node mock() {
        Node node = new Node();
        Node node1 = new Node();
        node.value = node1;
        node.name = "node";
        node1.value = node;
        node1.name = "node1";
        return node;
    }

    class Node {
        Node value;
        String name;
    }

    class Parsed {
        Parsed value;
        String name;
    }
    
    private Parsed parse(Node node, HashMap<Integer, Parsed> cache) {
        int i = node.hashCode();
        Parsed result = null;
        // 通过缓存记录解析结果,
        // 如果被解析对象已经被解析过了,则直接引用,避免陷入无限循环
        if (cache.containsKey(i)) {
            result = cache.get(i);
        } else {
            result = new Parsed();
            cache.put(i, result);
            result.name = node.name;
            result.value = parse(node.value,cache);
        }
        return result;
    }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容