Загрузка SnakeYAML в Guava MultiMap

Я пытаюсь загрузить файл Yaml в MultiMap с помощью SnakeYAML, но постоянно сталкиваюсь со следующим исключением: java.base/java.util.LinkedHashMap cannot be cast to com.google.common.collect.Multimap. Есть ли способ эффективно и эффективно загрузить объект SnakeYAML в MultiMap Guava? Я знаю, что вы можете сделать это с помощью обычных 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"

person Spotlightsrule    schedule 01.12.2018    source источник
comment
configData.load возвращает простую карту, которую нельзя преобразовать в Multimap. Вы должны взять карту, которую он вам дает, и вручную скопировать ее в Multimap.   -  person Louis Wasserman    schedule 02.12.2018
comment
Это сработает, но проблема связана с ранее упомянутыми повторяющимися значениями. Как избежать перезаписи повторяющихся значений SnakeYAML?   -  person Spotlightsrule    schedule 02.12.2018
comment
Можете ли вы добавить образец ввода YAML, который вы хотите проанализировать?   -  person Xaerxess    schedule 06.12.2018
comment
К исходному вопросу добавлен образец файла YAML с повторяющимися ключами.   -  person Spotlightsrule    schedule 07.12.2018


Ответы (1)


Мне удалось решить эту проблему, но я использовал регулярное выражение с обычными 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, которые допускают дублирование, как я изначально просил, но этот «хак» сработал для меня безупречно. Надеюсь, это поможет любому, кто хочет сделать что-то подобное.

person Spotlightsrule    schedule 13.12.2018