SnakeYAML 加载到 Guava MultiMap 中

SnakeYAML load into Guava MultiMap

我正在尝试使用 SnakeYAML 将 Yaml 文件加载到 MultiMap 中,但我一直遇到以下异常:java.base/java.util.LinkedHashMap cannot be cast to com.google.common.collect.Multimap。有什么方法可以高效且有效地将 SnakeYAML 对象加载到 Guava MultiMap 中吗?我知道您可以使用常规 HashMap 来执行此操作,但我的目标 Yaml 具有重复键,因此它需要使用 MultiMap。我在这里先向您的帮助表示感谢。我使用 SnakeYAML 填充 MultiMap 的代码如下:

//Read the config file
InputStream configIn;
try {
    configIn = FileUtil.loadFileAsStream(configPath);

    //Load the config file into the YAML object
    pluginConf = LinkedHashMultimap.create((Multimap<String, Object>) configData.load(configIn));
} 
catch(FileNotFoundException e){
    // TODO Auto-generated catch block
    e.printStackTrace();
}

编辑:具有重复键的示例 YAML

join:
  message: "JMessage1"
quit:
  message: "QMessage1"
join:
  message: "JMessage2"
quit:
  message: "QMessage2"
join:
  message: "JMessage3"
quit:
  message: "QMessage3"

我确实设法解决了这个问题,但我使用了正则表达式和常规 HashMap,而不是像我最初打算的那样使用 Guava Multimap。例如,这是一个具有重复键的 YAML 文件:

join:
  message: "JMessage1"
quit:
  message: "QMessage1"
join:
  message: "JMessage2"
quit:
  message: "QMessage2"

为了解析所有消息,我所做的只是简单地向每个重复的父键添加数字(join 变为 join1quit 变为 quit1,等等)。由于每个键中都有一个数字,因此可以使用以下正则表达式将它们轻松还原为仅说 joinquit:在遍历 HashMap 的 for 循环中使用 str.replaceAll("[^a-zA-Z.]", "").toLowerCase()。由于 HashMap 条目现在在循环中读取为 joinquitjoinquit,因此可以使用类似以下代码段的内容轻松获取它们的值:

if(entry.equals("join")){
    //Do stuff
}

之后,可以将值添加到 ArrayList 或其他集合中。在我的例子中,我使用了一个 ArrayList 并将 YAML 文件的属性分配给一个对象的实例变量。项目中我的 类 之一的以下片段实现了这一点:

//Iterate through the HashMap
for(Entry<?, ?> configEntry : pluginConf.entrySet()){
    //Get a string from the selected key that contains only lower-case letters and periods
    String entryKey = configEntry.getKey().toString().replaceAll("[^a-zA-Z.]", "").toLowerCase();

    //Search for join messages
    if(entryKey.equals("messages.join")){
        //Get the key name of the current entry
        String joinKeyName = configEntry.getKey().toString();

        //Create a join message object
        JoinMessage newJoinMessage = new JoinMessage(,
            configData.getString(joinKeyName + ".message")
        );

        //Add the join message object to the join message ArrayList
        joinMessages.add(newJoinMessage);

        //Add to the join message quantity
        joinMsgQuantity ++;
    }
}

并没有像我最初要求的那样真正使用允许重复的 HashMap,但是这个 "hack" 对我来说完美无缺。希望这可以帮助任何其他想要做这样的事情的人。