【问题标题】:iteratively traverse n amount of nested maps and lists迭代遍历 n 个嵌套映射和列表
【发布时间】:2016-05-16 19:37:52
【问题描述】:

我有一个通用地图,它可以包含一个地图列表,该列表可以迭代地包含另一个地图列表或另一个对象地图等。

映射我的地图;

我需要一种在不知道地图结构的情况下更新嵌套值的方法。例如说我的地图是这样的:

{mymap : myList[{'myObject' : 'someValue'}, {'myObject' : 'someOtherValue'}]}

基于某种路径表达式,例如“mymap.myList.myObject”,我需要能够将所有“myObject 值”替换为新值。

如何迭代遍历所有地图和列表以获取我想要的值?这需要是通用的,以便地图的结构可以改变,并且我根据路径表达式进行迭代。

【问题讨论】:

  • 您想用新对象替换地图中的键吗?还是使用 a 新对象?
  • 我想用新值替换某个键的值。
  • 所以基于上面的例子,我想用一个新值替换所有出现的“myObject”。

标签: java maps


【解决方案1】:

JsonPath 可能很合适。确保你的类路径上有这两个依赖项:

com.jayway.jsonpath:json-path:2.2.0
com.fasterxml.jackson.core:jackson-databind:2.7.0

然后:

import java.util.*;
import com.jayway.jsonpath.JsonPath;

public class Sandbox {

    private static class Widget {
        private final String id;

        public Widget(String id) {
            this.id = id;
        }

        @Override
        public String toString() {
            return "Widget{id='" + id + "'}";
        }
    }

    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        Map map1 = new HashMap();
        map1.put("myObject", new Widget("cog"));

        Map map2 = new HashMap();
        map2.put("myObject", new Widget("sprog"));

        Map root = new HashMap();
        root.put("myList", new ArrayList(Arrays.asList(map1, map2)));
        root.put("myObject", new Widget("frobulator"));

        System.out.println("BEFORE: " + root);

        // set the value of all 'myObject' nodes no matter how deeply nested
        JsonPath.parse(root).set("$..myObject", new Widget("novaDetonator"));

        System.out.println("AFTER:" + root);
    }
}

输出:

BEFORE: {myList=[{myObject=Widget{id='cog'}}, {myObject=Widget{id='sprog'}}], myObject=Widget{id='frobulator'}}
2016-05-16 13:44:44,337 [main] DEBUG  com.jayway.jsonpath.internal.path.CompiledPath - Evaluating path: $..['myObject']
2016-05-16 13:44:44,343 [main] DEBUG  com.jayway.jsonpath.internal.JsonContext - Set path $['myObject'] new value Widget{id='novaDetonator'}
2016-05-16 13:44:44,344 [main] DEBUG  com.jayway.jsonpath.internal.JsonContext - Set path $['myList'][0]['myObject'] new value Widget{id='novaDetonator'}
2016-05-16 13:44:44,344 [main] DEBUG  com.jayway.jsonpath.internal.JsonContext - Set path $['myList'][1]['myObject'] new value Widget{id='novaDetonator'}
AFTER:{myList=[{myObject=Widget{id='novaDetonator'}}, {myObject=Widget{id='novaDetonator'}}], myObject=Widget{id='novaDetonator'}}

当然,您的替换值可以是String 而不是Widget; JsonPath 两者都可以使用,这很好。

【讨论】:

    猜你喜欢
    • 2011-05-11
    • 1970-01-01
    • 2012-05-14
    • 2018-02-11
    • 2017-04-20
    • 2022-01-19
    • 2021-10-30
    • 2019-08-22
    相关资源
    最近更新 更多