Набор предметов со множеством заполнителей

#java #replace #minecraft #placeholder #bukkit

Вопрос:

В настоящее время я разрабатываю плагин для minecraft, который содержит множество элементов со множеством заполнителей.

У меня есть метод, который имеет два параметра: набор элементов и массив строк.

в массиве на нечетных позициях находятся переменные, а на четных позициях-значения, которыми они должны быть заменены.

Я хотел бы знать, какой наиболее эффективный метод замены этих переменных.

Мой код:

 public static ItemStack replace(ItemStack item, String... placeholders) {
    ItemMeta meta = item.getItemMeta();
    
    
    List<String> lore1 = meta.getLore();
    
    String lore = serializeLore(lore1);
    String name = meta.getDisplayName();
    
    for(int i = 0; i < placeholders.length; i =2) {
        lore = lore.replace((String)placeholders[i], (String)placeholders[i   1]);
        name = name.replace((String)placeholders[i], (String)placeholders[i   1]);
    }
    
    meta.setLore(Arrays.asList(lore.split("n")));
    meta.setDisplayName(name);
    
    item.setItemMeta(meta);
    return item;
}

private static String serializeLore(List<String> lore) {
    String result = "";
    
    for(int i = 0; i < lore.size(); i  ) {
        result  = lore.get(i)   (i   1 < lore.size() ? "n" : "");
    }
    return resu<
}
 

Например:

 replace(item, "%player%", "John", "%coins%", "2000", "%score%", "80");
 

Редактировать:
Пример знаний о предметах:

«amp;7Welcome назад и% — проигрыватель%!»
«»
«amp;7Crazy веселые мини-игры, чтобы играть с друзьями:»
«и F — %minigame1%»
«amp;Ф — %minigame2%»
«amp;Ф — %minigame3%»
«amp;Ф — %minigame4%»
«amp;Ф — %minigame5%»
«amp;Ф — %minigame6%»
«amp;Ф — %minigame7%»
«amp;Ф — %minigame8%»
«»
«amp;7Coins: amp;6%монетах%»
«amp;7Score: amp;2%балл%»
«amp;7Games играли: amp;9%gamesPlayed%»
«»
«amp;акликните играть!»
«amp;7%currentPlaying% в настоящее время играть!»

Комментарии:

1. Можете ли вы привести примеры того, как выглядят знания и данные об именах, прежде чем производить замену?

2. "amp;7Welcome Back amp;a%player%!" ""n "amp;7Crazy fun minigames to play with friends:" "amp;f - %minigame1%" "amp;f - %minigame2%" "amp;f - %minigame3%" "amp;f - %minigame4%" "amp;f - %minigame5%" "amp;f - %minigame6%" "amp;f - %minigame7%" "amp;f - %minigame8%" "" "amp;7Coins: amp;6%coins%" "amp;7Score: amp;2%score%" "amp;7Games Played: amp;9%gamesPlayed%" "" "amp;aClick to play!" "amp;7%currentPlaying% Currently playing!"

3. Кто-нибудь может мне помочь?

4. Вы сталкиваетесь с проблемами производительности из-за этого кода?

5. Если у вас нет никаких проблем с производительностью, то все должно быть в порядке. Может быть, использовать строку. Присоединяйтесь вместо метода serializeLore.

Ответ №1:

Я думаю, что производительность можно было бы улучшить, сократив количество вызовов для замены. Я подумал, что было бы быстрее просмотреть знания, найти каждый сайт замены в каждом знании, найдя строки, окруженные символами%, использовать этот ключ для поиска отображаемого значения (заполнителями может быть словарь вместо массива четных/нечетных пар), а затем использовать более производительный строковый конструктор для внесения изменений в строки.

Рассмотрим следующий псевдокод:

 public static ItemStack replace(ItemStack item, Dictionary<String, String> placeholders) {
    ItemMeta meta = item.getItemMeta();
    String lore = String.join("n", meta.getLore();
    String name = meta.getDisplayName();

    String modifiedLore = fillInReplacementValues(lore, placeholders);
    String modifiedName = fillInReplacementValues(name, placeholders);

    meta.setLore(modifiedLore.split('n');
    meta.setDisplayName(name);
    
    item.setItemMeta(meta);
    return item;
}

public static String fillInReplacementValues(String stringToModify, Dictionary<String, String> placeholders) {
    StringBuilder stringBuilder = new StringBuilder(stringToModify);
    String replacementMarker = "%";
    Boolean replacementMarkerFound = false;
    int replacementEndIndex = 0;

    // Start from the end of the lore string and look back
    for(int i = stringBuilder.length() - 1; i >= 0; i--) {
        // Did we find a marker end?
        if (replacementMarker == stringBuilder.charAt(i)) {
            if (replacementMarkerFound) {
                // We found the start and end indexes of %
                // Pull the name of the key field (coin, player etc)
                String replacementName = stringBuilder.substring(i   1, replacementEndIndex - 1);
                // replace the placeholder with value (ie %coin% with 1000)
                stringBuilder.replace(i, replacementEndIndex, placeholders[replacementName]);
                replacementMarkerFound = false;
            } else {
                replacementMarkerFound = true;
                replacementEndIndex = i;
            }
        }
    }
    return stringBuilder.toString();
}
 

Комментарии:

1. Спасибо за помощь, но этот код выдает мне ошибку компиляции! метод подстроки имеет только два параметра: подстрока(int, int);

2. Я пытался это исправить. В данный момент передо мной нет Java IDE. Почему опять же вам нужно улучшить производительность? Ваш плагин работает медленно из-за этого?

3. нет, но у меня есть система инвентаризации, которая заменяет больше переменных на товары…

4. Вот еще одна версия, которая пытается повысить производительность, не используя строку.заменить