Get Integer[] instead of ArrayList from Y

2019-09-08 12:00发布

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?

3条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-09-08 12:29

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);
查看更多
姐就是有狂的资本
3楼-- · 2019-09-08 12:29

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.

查看更多
Animai°情兽
4楼-- · 2019-09-08 12:29

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.

查看更多
登录 后发表回答