Problem with String#replace & saving a list of blocks

Discussion in 'Spigot Plugin Development' started by ProfiiQus, Aug 9, 2018.

  1. Hello spigoters!
    First, I have a problem with the String#replace/replaceAll method.
    Code (Text):
    public static void sendOwnMessage(Player reciever, String message) {
            PlayerDataFile pdf = new PlayerDataFile(reciever.getUniqueId());
         
            message.replace("%level%", ""+pdf.getLevel());
            message.replace("%experience%", ""+pdf.getExperience());
            message.replace("%player%", ""+reciever.getName());
            message.replace("%player_displayname%", ""+reciever.getDisplayName());
            message.replace("%xpbooster%", ""+pdf.getPersonalBooster());
            message.replace("%remaining_xp%", ""+pdf.getRemainingExperience());
            message.replace("%required_xp%", ""+pdf.getRequiredExperience());
         
            if(message.startsWith("#CENTER")) {
                String cmessage = message.substring(7);
                sendCenteredMessage(reciever, cmessage);
            } else {
                reciever.sendMessage(ChatColor.translateAlternateColorCodes('&', message));;
            }
        }
    PlayerDataFile is a class handling methods like #getLevel, #getExperience etc. These methods do work, as I can use them in a normal message sending (player#sendMessage). If I send a message with the normal method (player#sendMessage), the variables get replaced.

    If I use this method to send a message, it does not work - the message is sent and centered, but the variables are unchanged.

    Also, sorry for ""+pdf#getLevel(). I also tried String#valueOf(pdf#getLevel)) - which doesn't work aswell.

    The second issue I have is how to save a list of blocks.
    I tried to create a yml file where i set a path to ArrayList of Materials. It works - just the file looks like this
    Code (Text):
    Disabled-blocks:
    - !!org.bukkit.Material 'ACACIA_SAPLING'
    - !!org.bukkit.Material 'BIRCH_SAPLING'
    - !!org.bukkit.Material 'DARK_OAK_SAPLING'
    - !!org.bukkit.Material 'OAK_SAPLING'
    ...
    Is there any way I can like save a list of Strings and convert them into materials?

    Thanks for any advance!
     
  2. Alright so for the thing of replace use this code:
    Code (Java):
    message = message.replaceAll("%placeholder%", String.valueOf(%getter%));
    And for the materials just get the type of material in String (Material#toString, or String#valueOf(Material)) and save it as an string or as an array.
     
    • Agree Agree x 1
    • Winner Winner x 1
  3. Thanks very much!
     
  4. You are welcome!
     
  5. Use String.replace() instead of String.replaceAll(). replaceAll() uses regex, which is slower, and not needed in this case.
     
  6. String#replace requires a char, he is using a String.
     
  7. My bad, linked the wrong method.. this is the replace() he should be using.
     
    • Like Like x 1
    • Agree Agree x 1
  8. That's another option, however there is no (critical) error in using String#replaceAll().
     
  9. No one said there was a critical error. But why use a less performant method if it's not needed?
     
  10. I am not sure if using that method will get the plugin lose performance. But that's true, if there is a method that will give a better result, should be used.
     
  11. True, it's just it's a bit slower with no gain. Same functionality, slower speeds.

    But, I just took a look at String.replace(), and for my horror, String.replace() also compiles a pattern - as a literal, though, so it's still faster than replaceAll(). Since Spigot has Apache shaded, StringUtils.replace() is a lot better choice - or, even, as posted in the thread, this method:
    Code (Java):
    public static String replace (String source, String os, String ns) {
        if (source == null) {
            return null;
        }
        int i = 0;
        if ((i = source.indexOf(os, i)) >= 0) {
            char[] sourceArray = source.toCharArray();
            char[] nsArray = ns.toCharArray();
            int oLength = os.length();
            StringBuilder buf = new StringBuilder (sourceArray.length);
            buf.append (sourceArray, 0, i).append(nsArray);
            i += oLength;
            int j = i;
            // Replace all remaining instances of oldString with newString.
            while ((i = source.indexOf(os, i)) > 0) {
                buf.append (sourceArray, j, i - j).append(nsArray);
                i += oLength;
                j = i;
            }
            buf.append (sourceArray, j, sourceArray.length - j);
            source = buf.toString();
            buf.setLength (0);
        }
        return source;
    }

    It is slower, so yes it will give worse performance. Here are some benchmarks.
     
    • Informative Informative x 1