Get Integer[] instead of ArrayList<Integer> from YAML file

帅比萌擦擦* 提交于 2019-12-13 06:35:10

问题


I am parsing a YAML file

Props:
  Prop1 : [10, 22, 20]
  Prop2 : [20, 42, 60]

This gives me Map<String, Map<String, ArrayList<Integer>>> I would like to get Map<String, Map<String, Integer[]>> I do not want to convert List<Integer> to Integer[] in the code that reads the file. Can I change something in my YAML file?


回答1:


In contrast to my other answer, this one focuses on changing the YAML file. However, you also need to add some Java code to tell SnakeYaml how to load the tag you use.

You could add tags to the YAML sequences:

Props:
  Prop1 : !intarr [10, 22, 20]
  Prop2 : !intarr [20, 42, 60]

This need to be registered with SnakeYaml before loading:

public class MyConstructor extends Constructor {
    public MyConstructor() {
        this.yamlConstructors.put(new Tag("!intarr"),
                                  new ConstructIntegerArray());
    }

    private class ConstructIntegerArray extends AbstractConstruct {
        public Object construct(Node node) {
            final List<Object> raw = constructSequence(node);
            final Integer[] result = new Integer[raw.size()];
            for(int i = 0; i < raw.size(); i++) {
                result[i] = (Integer) raw.get(i);
            }
            return result;
        }
    }
}

You use it like this:

Yaml yaml = new Yaml(new MyConstructor());
Map<String, Map<String, Integer[]>> content =
    (Map<String, Map<String, Integer[]>>) yaml.load(myInput);



回答2:


From the snakeyaml documentation:

Default implementations of collections are:

 - List: ArrayList 
 - Map: LinkedHashMap (the order is implicitly defined)

There is no easy way to change it. Just call toArray() on a list and you're done.




回答3:


If the layout of your YAML file is stable, you can map it directly to a Java class, which defines the types of the inner properties:

public class Props {
    public Integer[] prop1;
    public Integer[] prop2;
}

public class YamlFile {
    public Props props;
}

Then, you can load it like this:

final Yaml yaml = new Yaml(new Constructor(YamlFile.class));
final YamlFile content = (YamlFile) yaml.load(myInput);
// do something with content.props.prop1, which is an Integer[]

I used standard Java naming for the properties, which would require you to change the keys in your YAML file to lower case:

props:
  prop1 : [10, 22, 20]
  prop2 : [20, 42, 60]

You can also keep the upper case, but you'd need to rename the Java properties accordingly.



来源:https://stackoverflow.com/questions/41685167/get-integer-instead-of-arraylistinteger-from-yaml-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!