具有许多占位符的 ItemStack

Posted

技术标签:

【中文标题】具有许多占位符的 ItemStack【英文标题】:ItemStack with many placeholders 【发布时间】:2021-10-07 10:18:27 【问题描述】:

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

我有一个有两个参数的方法: 一个 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%" "&7Score: &2%score%" "&7Games Played: &9%gamesPlayed%" "" "&a点击播放!" "&7%currentPlaying% 正在播放!"

【问题讨论】:

您能否举例说明在进行替换之前的知识和名称数据是什么样的? "&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!" 有人可以帮我吗? 您是否因为这段代码而面临性能问题? 如果你没有任何性能问题,那么你应该没问题。也许使用 string.Join 而不是 serializeLore 方法。 【参考方案1】:

我认为可以通过减少替换调用次数来提高性能。我认为循环遍历知识会更快,通过查找由 % 字符包围的字符串来找到每个知识中的每个替换站点,使用该键查找显示值(占位符可以是字典而不是偶数/奇数对数组),然后使用性能更高的 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();

【讨论】:

感谢您的帮助,但是这段代码给了我编译错误! substring 方法只有两个参数:substring(int, int); 我试图修复它。目前我面前没有 Java IDE。为什么又需要提高性能?您的插件是否因此而运行缓慢? 不,但我有一个库存系统,可以将更多变量替换为项目... 这是另一个试图通过不使用 string.replace 来提高性能的版本

以上是关于具有许多占位符的 ItemStack的主要内容,如果未能解决你的问题,请参考以下文章

在 PDO 中的执行函数中将 NULL 值绑定到具有关联数组的命名占位符的问题

在 HTML5 中不允许使用多行占位符的理由是啥?

创建具有不同颜色和字体的 UITextView 占位符

当输入和占位符具有不同的字体大小时,输入的占位符在 Chrome 中未对齐

Flyway 数据库迁移中占位符的用途

更改占位符的字体系列