简体   繁体   中英

Remove first character of string in O(1)

How can I represent a string of characters in java so that removing the first character of string takes O(1) time?

This question: on string character removing talks about using substring to remove first character of string in Java. But as found here on Java 7 changes the substring implementation runs in O(length of string) now. How can I remove first character in O(1) using Java?

I just want an alternative if possible using any other similar classes like StringBuffer, StringBuilder etc. that deal with strings and chars. Or any other way, surely there must be a way to remove the first character of a word in O(1).

There is no way to get the characters of a String without first copying them, which takes O(n) time as it has to transverse the entire string to copy it... unless you use reflection.

Now you talk about replacing the first letter in the string and replacing the first letter of each word in the string interchangeably. If you want to replace the first letter of each word, you're going to have to transverse the entire string which is O(n) time - there is just no other way.

If you only want to replace the first letter, you can use reflection, but I wouldn't suggest you actually do this, rather just use .substring(String) .

The method you're looking for:

/**
 * Replaces the first letter in a {@code String} in O(1) time.
 *
 * This uses reflection to change the values and will modify the
 * {@code String}s values. 
 *
 * @param str the {@code String} to modify.
 * @param letter the new first letter of the {@code String}.
 * @return {@code str}
 */
public static String replaceFirstLetter(String str, char letter) {
    if (str == null) {
        throw new NullPointerException("str cannot be null");
    }

    if (str.length() == 0) {
        throw new IllegalArgumentException("String cannot be empty");
    }

    try {
        Field value
                = str.getClass().getDeclaredField("value");

        value.setAccessible(true);

        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(value, value.getModifiers() & ~Modifier.FINAL);

        char[] values = (char[]) value.get(str);
        values[0] = letter;
        value.set(str, values);

    } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
        ex.printStackTrace();
        //This should never happen
    }

    return str;
}

Note that this method will modify the String you pass in, so this breaks the immutable rule of the String class and should not be used in production code. Also, it will probably be quicker to just transverse the string than it will be to use this method.

public static void main(String[] args) {
    String s = "Hello";
    replaceFirstLetter(s, 'Y');
    System.out.println(s);

    System.out.println(replaceFirstLetter("Hello", 'G'));
}

This demonstrates it quite nicely.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM