繁体   English   中英

找到某些条目名称时,如何在地图列表中转换/修改嵌套的 map?

[英]How to convert/modify nested map in list of maps when some entry name is found?

示例:这是它在yaml结构中的样子:

    states:
      entries:
        NONE: 
          value: core.lookups.states.none
          readonly: true
        MINOR:
          value: core.lookups.states.minor
          readonly: true
        MAJOR: 
          value: core.lookups.states.major
          readonly: true
      readonly: true

这是转换后的样子:

    states:
      entries:
        - key: "NONE"
          value: core.lookups.states.none
          readonly: true
        - key:  "MINOR"
          value: core.lookups.states.minor
          readonly: true
        - key: "MAJOR"
          value: core.lookups.states.major
          readonly: true
      readonly: true

注意:可能有更多条目,但每个条目中的关键“条目”都是相同的,例如:

        states:
          entries:
            - key: "NONE"
              value: core.lookups.states.none
              readonly: true
            - key:  "MINOR"
              value: core.lookups.states.minor
              readonly: true
            - key: "MAJOR"
              value: core.lookups.states.major
              readonly: true
          readonly: true
        states2:
          entries:
            - key: "NONE"
              value: core.lookups.states2.none
              readonly: true
            - key:  "MINOR"
              value: core.lookups.states2.minor
              readonly: true
            - key: "MAJOR"
              value: core.lookups.states2.major
              readonly: true
          readonly: true

注意:可能有更多条目,但每个条目中的关键“条目”都是相同的,例如:

public static void hashMapper(Map<String, Object> lookups) throws ParseException
    {
        for (Map.Entry<String, Object> entry : lookups.entrySet())
        {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (key.equals("entries"))
            {
                //modify the entry into list
            }
            else if (value instanceof Map)
            {
                Map<String, Object> subMap = (Map<String, Object>) value;
                hashMapper(subMap);
            }
            else
            {
                throw new IllegalArgumentException(String.valueOf(value));
            }

        }
    }

这是我到目前为止所做的。 每次当我找到具有条目值的键时,我都应该转换里面的条目。 各州也可以有另一个父键

下面是如何使用YAMLFactory中的 YAMLFactory 的快速演示:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class YamlTest {

    private static final ObjectMapper mapper = new ObjectMapper(new YAMLFactory());

    public static Map<String, State> convert(String yaml) throws Exception {

        Map<String, State> states = new LinkedHashMap<>();
        Map<String, Object> map = mapper.readValue(yaml, Map.class);

        for (String state : map.keySet()) {
            List<Entry> entryList = new ArrayList<>();
            Map<String, Object> statesMap = (Map<String, Object>) map.get(state);
            Map<String, Object> entriesMap = (Map<String, Object>) statesMap.get("entries");

            for (String entryKey : entriesMap.keySet()) {
                Map<String, Object> entryValueMap = (Map<String, Object>) entriesMap.get(entryKey);

                String value = (String) entryValueMap.get("value");
                Boolean readonly = (Boolean) entryValueMap.get("readonly");

                entryList.add(new Entry(entryKey, value, readonly));
            }

            Boolean readonlyState = (Boolean) statesMap.get("readonly");

            states.put(state, new State(entryList, readonlyState));
        }

        return states;
    }

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

        String input = "states:\n" +
                "  entries:\n" +
                "    NONE:\n" +
                "      value: core.lookups.states.none\n" +
                "      readonly: true\n" +
                "    MINOR:\n" +
                "      value: core.lookups.states.minor\n" +
                "      readonly: true\n" +
                "    MAJOR:\n" +
                "      value: core.lookups.states.major\n" +
                "      readonly: true\n" +
                "  readonly: true";

        Map<String, State> states = convert(input);
        String yamlOut = mapper.writeValueAsString(states);

        System.out.println(yamlOut);
    }
}

class State {

    public List<Entry> entries;
    public boolean readonly;

    public State(List<Entry> entries, boolean readonly) {
        this.entries = entries;
        this.readonly = readonly;
    }
}

class Entry {

    public String key;
    public String value;
    public boolean readonly;

    public Entry(String key, String value, boolean readonly) {
        this.key = key;
        this.value = value;
        this.readonly = readonly;
    }
}

这将打印:

---
states:
  entries:
  - key: "NONE"
    value: "core.lookups.states.none"
    readonly: true
  - key: "MINOR"
    value: "core.lookups.states.minor"
    readonly: true
  - key: "MAJOR"
    value: "core.lookups.states.major"
    readonly: true
  readonly: true

我使用了这些依赖项:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-yaml</artifactId>
    <version>2.9.8</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.9.8</version>
</dependency>

这是一个可能的解决方案:

public static void main(String[] args) {
    Map<String,Object> root = new HashMap<>();
    Map<String,Object> states = new HashMap<>();
    root.put("states", states);
    Map<String,Object> entries = new HashMap<>();
    states.put("entries", entries);
    Map<String,Object> none = new HashMap<>();
    entries.put("NONE", none);
    none.put("value", "core.lookups.states.none");
    none.put("readonly", true);
    Map<String,Object> minor = new HashMap<>();
    entries.put("MINOR", minor);
    minor.put("value", "core.lookups.states.minor");
    minor.put("readonly", true);
    Map<String,Object> major = new HashMap<>();
    entries.put("MAJOR", major);
    major.put("value", "core.lookups.states.minor");
    major.put("readonly", true);
    states.put("readonly", true);
    System.out.println(root);
    System.out.println(convertRoot(root));
}

private static Map<String,Object> convertRoot(Map<String,Object> root) {
    Map<String,Object> result = new LinkedHashMap<>();
    for (Map.Entry<String,Object> e: root.entrySet()) {
        String key = e.getKey();
        Object value = e.getValue();
        if (key.startsWith("states") && value instanceof Map) {
            value = convertStates((Map<String,Object>)value);
        }
        result.put(key, value);
    }
    return result;
}

private static Map<String,Object> convertStates(Map<String,Object> states) {
    Map<String,Object> result = new LinkedHashMap<>();
    for (Map.Entry<String,Object> e: states.entrySet()) {
        String key = e.getKey();
        Object value = e.getValue();
        if (key.equals("entries") && value instanceof Map) {
            value = toList((Map<String,Object>)value);
        }
        result.put(key, value);
    }
    return result;
}

private static List<Object> toList(Map<String,Object> map) {
    List<Object> result = new ArrayList<>();
    for (Map.Entry<String,Object> e: map.entrySet()) {
        String key = e.getKey();
        Object value = e.getValue();
        if (value instanceof Map) {
            Map<String,Object> elm
                    = new HashMap<>((Map<String,Object>)value);
            elm.put("key", key);
            value = elm;
        }
        result.add(value);
    }
    return result;
}

更新:就地转换

public static void main(String[] args) {
    Map<String,Object> root = new HashMap<>();
    Map<String,Object> states = new HashMap<>();
    root.put("states", states);
    Map<String,Object> entries = new HashMap<>();
    states.put("entries", entries);
    Map<String,Object> none = new HashMap<>();
    entries.put("NONE", none);
    none.put("value", "core.lookups.states.none");
    none.put("readonly", true);
    Map<String,Object> minor = new HashMap<>();
    entries.put("MINOR", minor);
    minor.put("value", "core.lookups.states.minor");
    minor.put("readonly", true);
    Map<String,Object> major = new HashMap<>();
    entries.put("MAJOR", major);
    major.put("value", "core.lookups.states.minor");
    major.put("readonly", true);
    states.put("readonly", true);
    System.out.println(root);
    convertRoot(root);
    System.out.println(root);
}

private static void convertRoot(Map<String,Object> root) {
    Map<String,Object> result = new LinkedHashMap<>();
    for (String key: root.keySet().toArray(new String[root.size()])) {
        Object value = root.get(key);
        if (key.startsWith("states") && value instanceof Map) {
            convertStates((Map<String,Object>)value);
        }
    }
}

private static void convertStates(Map<String,Object> states) {
    Map<String,Object> result = new LinkedHashMap<>();
    for (String key: states.keySet().toArray(new String[states.size()])) {
        Object value = states.get(key);
        if (key.startsWith("entries") && value instanceof Map) {
            states.put(key, toList((Map<String,Object>)value));
        }
    }
}

private static List<Object> toList(Map<String,Object> map) {
    List<Object> result = new ArrayList<>();
    for (Map.Entry<String,Object> e: map.entrySet()) {
        String key = e.getKey();
        Object value = e.getValue();
        if (value instanceof Map) {
            Map<String,Object> elm
                    = new HashMap<>((Map<String,Object>)value);
            elm.put("key", key);
            value = elm;
        }
        result.add(value);
    }
    return result;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM