具有许多占位符的 ItemStack

ItemStack with many placeholders

我目前正在开发一个 minecraft 插件,其中包含许多带有许多占位符的项目。

我有一个有两个参数的方法: 一个 ItemStack 和一个字符串数组。

数组中奇数位是变量,偶数位是需要替换的值

我想知道替换这些变量的最有效方法是什么。

我的代码:

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

例如:

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

编辑: 物品知识示例:

"&7欢迎回来 &a%player%!"
""
"&7 与朋友一起玩的疯狂有趣的迷你游戏:"
"&f - %minigame1%"
"&f - %minigame2%"
"&f - %minigame3%"
"&f - %minigame4%"
"&f - %minigame5%"
"&f - %minigame6%"
"&f - %minigame7%"
"&f - %minigame8%"
""
"&7Coins: &6%coins%"
"&7分数:&2%分数%"
"&7玩过的游戏:&9%gamesPlayed%"
""
"&a点击播放!"
"&7%currentPlaying% 当前正在播放!"

我认为可以通过减少替换调用次数来提高性能。我认为循环遍历知识会更快,通过查找被 % 字符包围的字符串在每个知识中找到每个替换站点,使用该键查找显示值(占位符可以是字典而不是数组 even/odd 对),然后使用性能更高的 StringBuilder 进行字符串修改。

考虑以下伪代码:

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();
}