Converting a (YAML) file to any MAP implementation

Dieter Nuytemans :

I was working on a spare time project where I needed to read values from a YAML file and store them in a HashMap, another YAML file had to be stored in a LinkedHashMap. I used an API to do the reading, some explanation was added in the code below (though I believe it's quite redundant). Only the method that returns a LinkedHashMap was included because the other one is practically identical.

Currently I'm using seperate methods for getting a HashMap and LinkedHashMap but noticed that the code was quite similar. So I wondered, would it be possible to write a general method that puts the paths and values from the YAML file into any Collections implementation (that are implementing Hash Table)? And if so, how could one accomplish that?

public LinkedHashMap<String, Object> fileToLinkedHashMap(File yamlFile)
{
    LinkedHashMap<String, Object> fileContents = new LinkedHashMap<String, Object>();

    //Part of the API I'm using, reads from YAML File and stores the contents
    YamlConfiguration config = YamlConfiguration.loadConfiguration(yamlFile);

    //Configuration#getKeys(true) Gets all paths within the read File
    for (String path : config.getKeys(true))
    {
        //Gets the value of a path
        if (config.get(path) != null)
            fileContents.put(path, config.get(path));
    }

    return fileContents;
}

Note: I know I'm currently not checking if the given file is a YAML file, this is redundant within this question.

Lino :

You can make use of functional interfaces (introduced in java 8) for this:

public void consumeFile(File yamlFile, BiConsumer<? super String, ? super Object> consumer){
    YamlConfiguration config = YamlConfiguration.loadConfiguration(yamlFile);
    for (String path : config.getKeys(true)){
        if (config.get(path) != null){
            consumer.accept(path, config.get(path));
        }
    }
}

Which can then be called with literally anything, you just have to provide a lambda which accepts 2 parameters:

// collect into a map
Map<String, Object> map = /* hash map, linked hash map, tree map, you decide */;
consumeFile(yamlFile, map::put);

// just print them, why not?
consumeFile(yamlFile, (key, value) -> System.out.println(key + " = " + value));

You see, the uses are possibly endless. Only limited by your use case and imagination.

If you can't use java 8 (you probably should though) there is still hope. As you both times return a Map you can decide when calling the method what map implementation you'd like to collect into:

public Map<String, Object> consumeFile(File yamlFile, Map<String, Object> map){
    YamlConfiguration config = YamlConfiguration.loadConfiguration(yamlFile);
    for (String path : config.getKeys(true)){
        if (config.get(path) != null){
            map.put(path, config.get(path));
        }
    }
    return map;
}

Which may be called like this:

Map<String, Object> map = consumeFile(yamlFile, new /*Linked*/HashMap<>());

Again what map implementation you want to use, you can decide for your needs.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=153421&siteId=1