ObjectMapper的objectNode、ArrayNode各种转换使用

news2024/9/29 17:35:00

在这里插入图片描述

目录

  • 说明
  • 实例代码

说明

本文章代码出自摸石头过河写出来的,隔天再写不一定写得出来,所以发个文章记录下。

为什么写这个代码
需求要求,有一段json字符串,数据结构是图下这样:

{
	"id": "1",
	"string": "sb",
	"double": "33",
	"long": "2",
	"boolean": "true",
	"domain": {
		"id": "1",
		"name": "大白",
		"org": {
			"code": "1"
		},
		"jd": [{
			"j": "false",
			"d": "4"
		}, {
			"j": "true",
			"d": "6"
		}]
	},
	"orgs": [{
		"code": "bb",
		"id": "true",
		"org": {
			"code": "1"
		},
		"sb": [{
			"s": "1"
		}, {
			"b": "true"
		}]
	}, {
		"code": "cc",
		"id": "false",
		"org": {
			"code": "1"
		},
		"sb": [{
			"s": "2"
		}, {
			"b": "false"
		}]
	}]
}

可以得知,所有属性都是string类型,又得知有个Attr类,里面放着json属性对应的类型,要求我们如果json里面有属性和Attr类里面名称对应的上,就要把string转换相对应的类型。

以上可能有点绕,举个栗子:图上有个id的属性,它的值是字符串的1,Attr类里面id对应的值是integer,所以最后的结果要是integer类型。

由于json数据结构不可知,只能穷举+递归针对处理:
1、基本数据类型
2、object类型
3、array类型
4、object类型中有array类型
5、array类型中有object类型

实例代码

package com.lq.demo1.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.lq.demo1.entity.Attr;
import com.lq.demo1.entity.Constants;
import lombok.extern.slf4j.Slf4j;

import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
public class TestService {


    public static void main(String[] args) throws JsonProcessingException {

        String json = "{\n" +
                "\t\"id\": \"1\",\n" +
                "\t\"string\": \"sb\",\n" +
                "\t\"double\": \"33\",\n" +
                "\t\"long\": \"2\",\n" +
                "\t\"boolean\": \"true\",\n" +
                "\t\"domain\": {\n" +
                "\t\t\"id\": \"1\",\n" +
                "\t\t\"name\": \"大白\",\n" +
                "\t\t\"org\": {\n" +
                "\t\t\t\"code\": \"1\"\n" +
                "\t\t},\n" +
                "\t\t\"jd\": [{\n" +
                "\t\t\t\"j\": \"false\",\n" +
                "\t\t\t\"d\": \"4\"\n" +
                "\t\t}, {\n" +
                "\t\t\t\"j\": \"true\",\n" +
                "\t\t\t\"d\": \"6\"\n" +
                "\t\t}]\n" +
                "\t},\n" +
                "\t\"orgs\": [{\n" +
                "\t\t\"code\": \"bb\",\n" +
                "\t\t\"id\": \"true\",\n" +
                "\t\t\"org\": {\n" +
                "\t\t\t\"code\": \"1\"\n" +
                "\t\t},\n" +
                "\t\t\"sb\": [{\n" +
                "\t\t\t\"s\": \"1\"\n" +
                "\t\t}, {\n" +
                "\t\t\t\"b\": \"true\"\n" +
                "\t\t}]\n" +
                "\t}, {\n" +
                "\t\t\"code\": \"cc\",\n" +
                "\t\t\"id\": \"false\",\n" +
                "\t\t\"org\": {\n" +
                "\t\t\t\"code\": \"1\"\n" +
                "\t\t},\n" +
                "\t\t\"sb\": [{\n" +
                "\t\t\t\"s\": \"2\"\n" +
                "\t\t}, {\n" +
                "\t\t\t\"b\": \"false\"\n" +
                "\t\t}]\n" +
                "\t}]\n" +
                "}";

        log.info("老:{}", json);
        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode objectNode = (ObjectNode) objectMapper.readTree(json);

        Attr a = Attr.builder().id(1).attributeName("id").attributeType("INTEGER").parentId(-1).build();
        Attr b = Attr.builder().id(2).attributeName("string").attributeType("STRING").parentId(-1).build();
        Attr c = Attr.builder().id(3).attributeName("double").attributeType("INTEGER").parentId(-1).build();
        Attr d = Attr.builder().id(4).attributeName("long").attributeType("LONG").parentId(-1).build();
        Attr e = Attr.builder().id(5).attributeName("boolean").attributeType("BOOLEAN").parentId(-1).build();

        Attr f = Attr.builder().id(6).attributeName("orgs").attributeType("JSONARRAY").parentId(-1).build();
        Attr g = Attr.builder().id(7).attributeName("code").attributeType("STRING").parentId(6).build();
        Attr h = Attr.builder().id(7).attributeName("id").attributeType("BOOLEAN").parentId(6).build();
        Attr l1 = Attr.builder().id(13).attributeName("org").attributeType("JSONOBJECT").parentId(6).build();
        Attr m1 = Attr.builder().id(14).attributeName("code").attributeType("INTEGER").parentId(13).build();
        Attr m11 = Attr.builder().id(15).attributeName("sb").attributeType("JSONARRAY").parentId(6).build();
        Attr m12 = Attr.builder().id(16).attributeName("s").attributeType("INTEGER").parentId(15).build();
        Attr m13 = Attr.builder().id(17).attributeName("b").attributeType("BOOLEAN").parentId(15).build();


        Attr i = Attr.builder().id(8).attributeName("domain").attributeType("JSONOBJECT").parentId(-1).build();
        Attr j = Attr.builder().id(9).attributeName("id").attributeType("INTEGER").parentId(8).build();
        Attr k = Attr.builder().id(10).attributeName("name").attributeType("STRING").parentId(8).build();
        Attr l = Attr.builder().id(11).attributeName("org").attributeType("JSONOBJECT").parentId(8).build();
        Attr m = Attr.builder().id(12).attributeName("code").attributeType("INTEGER").parentId(11).build();
        Attr m8 = Attr.builder().id(18).attributeName("jd").attributeType("JSONARRAY").parentId(8).build();
        Attr m9 = Attr.builder().id(19).attributeName("j").attributeType("BOOLEAN").parentId(18).build();
        Attr m20 = Attr.builder().id(20).attributeName("d").attributeType("INTEGER").parentId(18).build();


        List<Attr> attrs = new LinkedList<>();
        attrs.add(m8);
        attrs.add(m9);
        attrs.add(m20);

        attrs.add(a);
        attrs.add(b);
        attrs.add(c);
        attrs.add(d);
        attrs.add(e);
        attrs.add(f);
        attrs.add(g);
        attrs.add(h);
        attrs.add(i);
        attrs.add(j);
        attrs.add(k);
        attrs.add(l);
        attrs.add(m);
        attrs.add(l1);
        attrs.add(m1);
        attrs.add(m11);
        attrs.add(m12);
        attrs.add(m13);
        tree(attrs);
        log.info("树结构:{}", attrs.toString());

        Iterator<Map.Entry<String, JsonNode>> fields = objectNode.fields();
        while (fields.hasNext()) {
            Map.Entry<String, JsonNode> next = fields.next();
            String key = next.getKey();
            JsonNode value = next.getValue();
            for (Attr dto : attrs) {
                String attributeType = dto.getAttributeType();
                if (dto.getAttributeName().equals(key)) {
                    if (!attributeType.equals(Constants.JSONARRAY) && !attributeType.equals(Constants.JSONOBJECT)) {
                        //先把最外层的基本类型给解决掉
                        baseNode(objectNode, key, value, attributeType);
                    } else if (attributeType.equals(Constants.JSONOBJECT)) {
                        //第一层的key
                        objectNode(objectNode, key, key, value, attributeType, attrs);
                    } else if (attributeType.equals(Constants.JSONARRAY)) {
                        arraryNode(objectNode, key, key, attributeType, attrs);
                    }
                }
            }
        }

        log.info("新:{}", objectNode.toString());
    }

    /**
     * @param objectNode      原始数据
     * @param key           原始数据中的key
     * @param value         key的value 需要转换类型
     * @param attributeType 转换的类型
     */
    public static void baseNode(ObjectNode objectNode, String key, JsonNode value, String attributeType) {
        //基础类型设置值
        if (attributeType.equals(Constants.DOUBLE)) {
            objectNode.put(key, value.asDouble());
        } else if (attributeType.equals(Constants.INTEGER)) {
            objectNode.put(key, value.asInt());
        } else if (attributeType.equals(Constants.LONG)) {
            objectNode.put(key, value.asLong());
        } else if (attributeType.equals(Constants.BOOLEAN)) {
            objectNode.put(key, value.asBoolean());
        }
    }

    /**
     * @param rootObjectNode      原始数据
     * @param rootKey       原始数据中key
     * @param attrKey       追加要和attr name 拼接使用的key
     * @param attributeType
     * @param attrs
     */
    public static void arraryNode(ObjectNode rootObjectNode, String rootKey, String attrKey, String attributeType, List<Attr> attrs) {
        if (attributeType.equals(Constants.JSONARRAY)) {
            ArrayNode jsonNodes = rootObjectNode.withArray(rootKey);
            for (int i = 0; i < jsonNodes.size(); i++) {
                JsonNode node = jsonNodes.get(i);
                Iterator<Map.Entry<String, JsonNode>> fields = node.fields();
                while (fields.hasNext()) {
                    Map.Entry<String, JsonNode> next = fields.next();
                    String key = next.getKey();
                    String dkey = attrKey + "." + key;
                    //子属性node
                    JsonNode nextValue = next.getValue();
                    for (Attr attr : attrs) {
                        if (dkey.equals(attr.getAttributeName())) {
                            String attributeType1 = attr.getAttributeType();
                            if (!attributeType1.equals(Constants.JSONOBJECT) && !attributeType1.equals(Constants.JSONARRAY)) {
                                //怎么修改值类型?
                                ObjectNode objectNode = (ObjectNode) node;
                                if (attributeType1.equals(Constants.DOUBLE)) {
                                    objectNode.put(key, nextValue.asInt());
                                } else if (attributeType1.equals(Constants.INTEGER)) {
                                    objectNode.put(key, nextValue.asInt());
                                } else if (attributeType1.equals(Constants.LONG)) {
                                    objectNode.put(key, nextValue.asLong());
                                } else if (attributeType1.equals(Constants.BOOLEAN)) {
                                    objectNode.put(key, nextValue.asBoolean());
                                } else if (attributeType1.equals(Constants.STRING)) {
                                    objectNode.put(key, nextValue.asText());
                                }
                            } else if (attributeType1.equals(Constants.JSONOBJECT)) {
                                ObjectNode objectNode = (ObjectNode) node;
                                objectNode(objectNode, key, dkey, nextValue, attributeType1, attrs);
                            } else if (attributeType1.equals(Constants.JSONARRAY)) {
                                ObjectNode objectNode = (ObjectNode) node;
                                arraryNode(objectNode, key, dkey, attributeType1, attrs);
                            }
                        }
                    }
                }
            }
        }

    }


    /**
     * @param rootObjectNode      原始数据
     * @param rootKey       对象名称
     * @param attrKey
     * @param childJsonNode 对象里面的所有属性
     * @param attributeType
     * @param attrs
     */
    public static void objectNode(ObjectNode rootObjectNode, String rootKey, String attrKey, JsonNode childJsonNode,
                              String attributeType, List<Attr> attrs) {
        if (attributeType.equals(Constants.JSONOBJECT)) {
            Iterator<Map.Entry<String, JsonNode>> fields = childJsonNode.fields();
            while (fields.hasNext()) {
                Map.Entry<String, JsonNode> next = fields.next();
                String key = next.getKey();
                String dkey = attrKey + "." + key;
                //子属性node
                JsonNode nextValue = next.getValue();
                for (Attr attr : attrs) {
                    if (dkey.equals(attr.getAttributeName())) {
                        String attributeType1 = attr.getAttributeType();
                        if (!attributeType1.equals(Constants.JSONOBJECT) && !attributeType1.equals(Constants.JSONARRAY)) {
                            ObjectNode objectNode = rootObjectNode.with(rootKey);
                            if (attributeType1.equals(Constants.DOUBLE)) {
                                objectNode.put(key, nextValue.asDouble());
                            } else if (attributeType1.equals(Constants.INTEGER)) {
                                objectNode.put(key, nextValue.asInt());
                            } else if (attributeType1.equals(Constants.LONG)) {
                                objectNode.put(key, nextValue.asLong());
                            } else if (attributeType1.equals(Constants.BOOLEAN)) {
                                objectNode.put(key, nextValue.asBoolean());
                            }
                        } else if (attributeType1.equals(Constants.JSONOBJECT)) {
                            ObjectNode objectNode = rootObjectNode.with(rootKey);
                            objectNode(objectNode, key, dkey, nextValue, attributeType1, attrs);
                        } else if (attributeType1.equals(Constants.JSONARRAY)) {
                            ObjectNode objectNode = rootObjectNode.with(rootKey);
                            arraryNode(objectNode, key, dkey, attributeType1, attrs);
                        }
                    }
                }
            }
        }
    }

    /**
     * 树节点处理名称拼接  查询sql的id必须按照升序排序 不然方法无效
     *
     * @param all
     */
    public static void tree(List<Attr> all) {
        //按照id升序 因为Attr是类似tree结构的数据,如果是object类型,一个属性的名称例如就是domain.id  为什么不直接拿id,因为不同节点id可能是string可能是integer,所以要通过对象.属性去重命名  外面匹配也是一样,如果有嵌套的数据,要自行处理名称和Attr重置后的名称匹配,才能得知真正类型是什么
        all.stream().sorted(Comparator.comparing(Attr::getId)).collect(Collectors.toList());
        for (Attr a : all) {
            if (a.getParentId().intValue() != -1) {
                setName(a, all);
            }
        }
    }

    public static void setName(Attr b, List<Attr> all) {
        for (Attr attribute : all) {
            if (b.getParentId().equals(attribute.getId())) {
                b.setAttributeName(attribute.getAttributeName() + "." + b.getAttributeName());
            }
        }
    }
}

主要难点,就是objectNode和arrayNode怎么去设置值,当时困扰了我很久,因为对ObjectMapper不熟悉,里面很多方法不知道,后面看了下源码才知道,主要的坑有以下几点:

  1. 所有的数据修改,都可以用ObjectNode.put方法去改,即使是arrayNode类型,之前不知道怎么去修改,妄想自己组装map去覆盖,结果失败。。
  2. 递归传递的值一定要捋清楚,很容易穿错原数据结构,比如对象套对象、对象套集合、集合套对象套集合等等这种很扭曲很恶心的结构,在针对对象和集合这两个类型卡我很久!!!
  3. JsonNode可以强转换为ObjectNode类型,之后就可以针对这个节点的值去修改,例如arrayNode我一直在查怎么修改,很多人都说删除原节点,自己写个新的节点加进去,这种很麻烦很麻烦很麻烦,尤其各种变态结构,极其容易出错(我没写成功过)
  4. ObjectNode.with、ObjectNode.withArray是object、array类型获取节点不同方式,里面填的是key名称,会去同一层找到这个key的所有属性返回,这个就是从源码看到的,百度我没找到,各个类去翻才找到。。。
  5. 如何去循环一个node,方法是JsonNode.fields();,JsonNode里面有很多方法,可以去源码看看,也有拿所有key的,但是 JsonNode.fields(); 能拿到所有的key-value键值对,其他的要么只能拿key,要么只能拿value,而且value还不是jsonNode类型,后面极其不好处理

就先说到这 \color{#008B8B}{ 就先说到这} 就先说到这
在下 A p o l l o \color{#008B8B}{在下Apollo} 在下Apollo
一个爱分享 J a v a 、生活的小人物, \color{#008B8B}{一个爱分享Java、生活的小人物,} 一个爱分享Java、生活的小人物,
咱们来日方长,有缘江湖再见,告辞! \color{#008B8B}{咱们来日方长,有缘江湖再见,告辞!} 咱们来日方长,有缘江湖再见,告辞!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/128863.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习之特征工程详解

特征工程是指使用专业的背景知识和技巧处理数据&#xff0c;使得特征能在机器学习算法上发生更好的作用的过程。更好的特征意味着更强的灵活性&#xff0c;只需简单模型就能得到更好的结果&#xff0c;因此&#xff0c;特征工程在机器学习中占有相当重要的地位&#xff0c;可以…

pwr | 谁说样本量计算是个老大难问题!?(一)(分类变量篇)

1写在前面 估算前瞻性研究的样本量是我们在招募受试者之前首先要做的事情之一。&#x1f618; 招募受试者太少会无法得到准确的答案&#xff0c;招募的太多又是巨大的浪费&#xff0c;所以需要估算最佳的受试者数量。&#x1f9d0; 本期我们介绍一下如何使用pwr包进行样本量的估…

Android性能优化——内存泄漏的根本原因

什么是内存泄露 什么是内存泄露&#xff0c;通俗的来说就是堆中的一些对象已经不会再被使用了&#xff0c;但垃圾收集器却无法将它们从内存中清除。 内存泄漏很严重的问题&#xff0c;因为它会阻塞内存资源并随着时间的推移降低系统性能。如果不进行有效的处理&#xff0c;最…

CS5518设计MIPI转LVDS转换方案/MIPI转LVDS方案芯片

CS5518是一个MIPI DSI输入&#xff0c;LVDS输出转换芯片。MIPI DSI最多支持4个车道&#xff0c;每个车道的最大运行速度 为1Gbps。LVDS支持18或24位像素&#xff0c;25MHz到154MHz&#xff0c;通过VESA或JEIDA格式。它只能使用一个1.8V电源&#xff0c;节省 成本&#xff0c;优…

Linux下的目录结构Linux基本命令(程序员必学)

目录 1.Linux下的目录结构 2.Linux的常用命令 2.1.# 与 $ 提示的区别 2.2.ifconfig 查看ip地址 2.3.su 命令格式 2.4.cd 2.5. 目录查看 2.6. 查看文件内容 2.7.创建目录及文件 2.8.复制和移动 2.9.其他 3. vim一般使用 1.Linux下的目录结构 /usr全称&#xff08…

Live Home 3D Pro - 用于公寓和房屋的室内设计,支持 3D 实时渲染

Live Home 3D Pro - 用于公寓和房屋的室内设计&#xff0c;支持 3D 实时渲染 Live Home 3D Pro是一个直观的应用程序&#xff0c;用于公寓和房屋的室内设计&#xff0c;以及几乎任何复杂的景观。专业版提供了一套扩展的工具和独特的出口质量。 下载 ► Live Home 3D Pro 下载安…

Java反射专题——基础知识一

反射 反射机制 java Reflection 反射机制允许程序在执行期借助于Reflection Api取得任何类的内部信息&#xff08;比如成员变量&#xff0c;构造器&#xff0c;成员方法等等&#xff09;&#xff0c;并能操作对象的属性及方法。反射在设计模式和框架底层都会用到。加载完类之…

我眼中的代理模式

一.什么是代理模式&#xff1f; 举个简单的例子就是比如你相亲的女孩想跟你要个10W彩礼&#xff0c;但是她不好意思直接跟你说啊。这时候就媒婆就说我去跟小伙子说。有什么回应我告诉你。然后媒婆就先夸女方怎么怎么优秀&#xff0c;然后落到中心思想要钱。这里面相亲的女孩子就…

PL点亮LED灯

PL点亮LED灯 LED硬件 开发板在PL端给了一个LED灯&#xff0c;电压给低的时候才导通&#xff0c;才亮。然后需要看原理图确定具体是用的PL的哪个管脚以便进行控制。 Vivado 工程创建 打开创建新工程选择工程名和工程目录&#xff08;不能有中文路径&#xff0c;也不能太长&…

什么品牌的蓝牙耳机音质最好?高品质蓝牙耳机排行榜

近年来&#xff0c;大量的蓝牙耳机品牌厂商涌入市场&#xff0c;蓝牙耳机的需求不断提高&#xff0c;但质量一直是人们担心的问题&#xff0c;今天就为大家盘点几款当前音质表现不错的真无线蓝牙耳机。 一、南卡小音舱蓝牙耳机 发声单元&#xff1a;13.3mm 网友推荐系数&…

hex文件格式剖析,以及hex与bin文件互相转换

大家好&#xff0c;我是学电子的小白白。 熟悉单片机开发的朋友&#xff0c;应该经常见到*.hex后缀的文件&#xff0c;它是单片机和嵌入式工程编译输出的一种常见的目标文件格式&#xff08;比如keil就能编译输出hex文件&#xff09;&#xff0c;通过烧写工具把它下载到单片机…

【SpringBoot项目实战】图片压缩包上传、解压、存储等等一套流程教学

【SpringBoot项目实战】图片压缩包上传、解压、存储等等一套流程教学前言一、压缩包上传1、接口实现2、获取压缩包的文件名和文件路径二、压缩包解压并保存1、处理压缩包文件方法解压缩步骤&#xff1a;2、接口中实现处理压缩包三、总结前言 之前一直用的zip4j来对压缩包进行操…

开源项目推荐 | 中科院自动化所历时9年打造的类脑认知智能引擎“智脉”正式开源部署至OpenI启智社区

​人脑能够自组织地协同数百项认知功能&#xff0c;灵活适应复杂多变的环境。如何整合多尺度生物可塑性法则来构建具有生物合理性和计算高效性的神经网络模型是类脑人工智能和计算神经科学领域共同关注和面临的重要挑战。 中国科学院自动化研究所类脑认知智能研究组历时9年&am…

通关算法题之 ⌈动态规划⌋

动态规划 动态规划是什么&#xff1f;解决动态规划问题有什么技巧&#xff1f;如何学习动态规划&#xff1f; 首先&#xff0c;动态规划问题的一般形式就是求最值。动态规划其实是运筹学的一种最优化方法&#xff0c;只不过在计算机问题上应用比较多&#xff0c;比如说让你求…

蓝桥杯寒假集训第二天(分巧克力)

没有白走的路&#xff0c;每一步都算数&#x1f388;&#x1f388;&#x1f388; 题目描述&#xff1a; 有很多的巧克力块&#xff0c;需要设计一个程序&#xff0c;让手艺师傅切出来的巧克力既满足切出来的巧克力的份数达到客户要求的份数&#xff0c;并且切出来的巧克力块尽…

硬盘图片丢失怎么办?看看这常见的三种恢复方法

电脑硬盘能够帮助我们存储各种各样的数据&#xff0c;比如图片数据&#xff0c;而随着这些充满回忆的图片积累的越来越多&#xff0c;难免会手误删除或其他原因导致丢失&#xff0c;那么对于电脑硬盘上丢失的图片如何恢复呢&#xff1f;在这里你可以了解到硬盘图片丢失常见原因…

python—subprocess模块常用方法介绍

目录 subprocess.run() subprocess.Popen() subprocess.call() subprocess.check_call() subprocess.getstatusoutput() subprocess.getoutput() subprocess.check_output() subprocess是子流程&#xff0c;即进程的意思&#xff0c;该模块可以启动一个新进程&#xff0…

印度电线标准IS 694(R2020),印度插头标准IS 1293(R2020)

印度电线标准IS 694&#xff08;R2020) https://download.csdn.net/download/std86021/87328675POLYVINYLCHLORIDEINSULATEDUNSHEATHEDANDSHEATH更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/std86021/87328675 补丁一&#xff1a;IS694Amd…

已获1000 万美元战略融资,Web3链游#Delysium 有何魔力?

这周社区推文关注了AIGC在游戏领域中的创新应用&#xff0c;在Web3领域中&#xff0c;有哪些值得关注的链游项目呢&#xff1f;Mixlab小杜AIGC 与游戏机制创新玩法结合已成为潮流趋势&#xff0c;如游戏内容资产生成、智能NPC设计与自定义游戏玩法等都有非常大的探索空间。Web3…

【ACWING】【BFS】【844走迷宫】【845八数码】

一、走迷宫 给定一个 nm的二维整数数组&#xff0c;用来表示一个迷宫&#xff0c;数组中只包含 0 或 1&#xff0c;其中 0表示可以走的路&#xff0c;1 表示不可通过的墙壁。 最初&#xff0c;有一个人位于左上角 (1,1)处&#xff0c;已知该人每次可以向上、下、左、右任意一…