SnakeYAML загрузить в Guava MultiMap - PullRequest
0 голосов
/ 02 декабря 2018

Я пытаюсь загрузить файл Yaml в MultiMap, используя SnakeYAML, но я продолжаю сталкиваться со следующим исключением: java.base/java.util.LinkedHashMap cannot be cast to com.google.common.collect.Multimap.Есть ли способ эффективно и эффективно загрузить объект SnakeYAML в Guava MultiMap?Я знаю, что вы можете сделать это с обычными HashMaps, но у моего целевого Yaml есть дубликаты ключей, поэтому он требует использования MultiMaps.Спасибо за помощь заранее.Мой код для заполнения MultiMap с использованием SnakeYAML выглядит следующим образом:

//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"

1 Ответ

0 голосов
/ 13 декабря 2018

Мне удалось решить эту проблему, но я использовал регулярные выражения с обычными HashMaps вместо мультикарт Guava, как я изначально планировал.Например, вот файл YAML с дублирующимися ключами:

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

Чтобы разобрать все сообщения, я просто добавил числа к каждому из повторяющихся родительских ключей (joinстановится join1, quit становится quit1 и т. д.).Поскольку в каждом ключе есть число, их можно легко вернуть обратно к простому произнесению join или quit со следующим регулярным выражением: str.replaceAll("[^a-zA-Z.]", "").toLowerCase() в цикле for, который выполняет итерацию по HashMap.Поскольку записи HashMap теперь просто читаются как join, quit, join, quit при прохождении через цикл, их значения можно легко получить с помощью чего-то вроде следующего фрагмента:

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 ++;
    }
}

На самом деле я не использую HashMaps, которые допускают дубликаты, как я изначально просил, но этот «взлом» работал без нареканий.Надеюсь, это поможет кому-то еще, желающему сделать что-то подобное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...