java 在Java中替换字符串的第一个字母?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2447427/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 21:12:10  来源:igfitidea点击:

Replace the first letter of a String in Java?

javastring

提问by froadie

I'm trying to convert the first letter of a string to lowercase.

我正在尝试将字符串的第一个字母转换为小写。

value.substring(0,1).toLowerCase() + value.substring(1)

This works, but are there any better ways to do this?

这有效,但有没有更好的方法来做到这一点?

I could use a replace function, but Java's replace doesn't accept an index. You have to pass the actual character/substring. It could be done like this:

我可以使用替换函数,但 Java 的替换不接受索引。您必须传递实际的字符/子字符串。可以这样做:

value.replaceFirst(value.charAt(0), value.charAt(0).toLowerCase())

Except that replaceFirst expects 2 strings, so the value.charAt(0)s would probably need to be replaced with value.substring(0,1).

除了 replaceFirst 需要 2 个字符串,因此value.charAt(0)s 可能需要替换为value.substring(0,1).

Is there any standard way to replace the first letter of a String?

是否有任何标准方法来替换字符串的第一个字母?

回答by Maxym

I would suggest you to take a look at Commons-Langlibrary from Apache. They have a class

我建议您查看Apache 的Commons-Lang库。他们有一堂课

StringUtils

which allows you to do a lot of tasks with Strings. In your case just use

它允许您使用字符串执行许多任务。在你的情况下,只需使用

StringUtils.uncapitalize( value )

read here about uncapitalizeas well as about other functionality of the class suggested

在此处阅读有关取消大写以及建议的类的其他功能的信息

Added:my experience tells that Coomon-Lang is quite good optimized, so if want to know what is better from algorithmistic point of view, you could take a look at its source from Apache.

补充:我的经验告诉我们 Coomon-Lang 优化得相当好,所以如果想从算法的角度知道什么更好,你可以看看它来自 Apache 的源代码。

回答by T.J. Crowder

The downside of the code you used (and I've used in similar situations) is that it seems a bit clunky and in theory generates at least two temporary strings that are immediately thrown away. There's also the issue of what happens if your string is fewer than two characters long.

您使用的代码(我在类似情况下使用过)的缺点是它看起来有点笨拙,理论上至少会生成两个立即丢弃的临时字符串。还有一个问题,如果您的字符串少于两个字符长会发生什么。

The upside is that you don't reference those temporary strings outside the expression (leaving it open to optimization by the bytecode compiler or the JIT optimizer) and your intent is clear to any future code maintainer.

好处是您不会在表达式之外引用那些临时字符串(让字节码编译器或 JIT 优化器对其进行优化),并且您的意图对任何未来的代码维护者来说都是明确的。

Barring your needing to do several million of these any given second anddetecting a noticeable performance issue doing so, I wouldn't worry about performance and would prefer clarity. I'd also bury it off in a utility class somewhere. :-) See also jambjo's response to another answer pointing out that there's an important difference between String#toLowerCaseand Character.toLowerCase. (Edit: The answer and therefore comment have been removed. Basically, there's a big difference related to locales and Unicode and the docs recommend using String#toLowerCase, not Character.toLowerCase; more here.)

除非您需要在任何给定的时间内执行数百万个这样的操作检测到明显的性能问题,否则我不会担心性能并且更喜欢清晰。我也会把它埋在某个地方的实用程序类中。:-) 另请参阅 jambjo 对另一个答案的回应,指出String#toLowerCase和之间存在重要区别Character.toLowerCase。(编辑:答案和评论已被删除。基本上,与语言环境和 Unicode 相关的有很大差异,文档建议使用String#toLowerCase, 不是Character.toLowerCase;在这里更多

EditBecause I'm in a weird mood, I thought I'd see if there was a measureable difference in performance in a simple test. There is. It could be because of the locale difference (e.g., apples vs. oranges):

编辑因为我的心情很奇怪,所以我想我会在一个简单的测试中看看性能是否存在可测量的差异。有。这可能是因为地区差异(例如,苹果与橙子):

public class Uncap
{
    public static final void main(String[] params)
    {
        String  s;
        String  s2;
        long    start;
        long    end;
        int     counter;

        // Warm up
        s = "Testing";
        start = System.currentTimeMillis();
        for (counter = 1000000; counter > 0; --counter)
        {
            s2 = uncap1(s);
            s2 = uncap2(s);
            s2 = uncap3(s);
        }

        // Test v2
        start = System.currentTimeMillis();
        for (counter = 1000000; counter > 0; --counter)
        {
            s2 = uncap2(s);
        }
        end = System.currentTimeMillis();
        System.out.println("2: " + (end - start));

        // Test v1
        start = System.currentTimeMillis();
        for (counter = 1000000; counter > 0; --counter)
        {
            s2 = uncap1(s);
        }
        end = System.currentTimeMillis();
        System.out.println("1: " + (end - start));

        // Test v3
        start = System.currentTimeMillis();
        for (counter = 1000000; counter > 0; --counter)
        {
            s2 = uncap3(s);
        }
        end = System.currentTimeMillis();
        System.out.println("3: " + (end - start));

        System.exit(0);
    }

    // The simple, direct version; also allows the library to handle
    // locales and Unicode correctly
    private static final String uncap1(String s)
    {
        return s.substring(0,1).toLowerCase() + s.substring(1);
    }

    // This will *not* handle locales and unicode correctly
    private static final String uncap2(String s)
    {
        return Character.toLowerCase(s.charAt(0)) + s.substring(1);
    }

    // This will *not* handle locales and unicode correctly
    private static final String uncap3(String s)
    {
        StringBuffer sb;

        sb = new StringBuffer(s);
        sb.setCharAt(0, Character.toLowerCase(sb.charAt(0)));
        return sb.toString();
    }
}

I mixed up the order in various tests (moving them around and recompiling) to avoid issues of ramp-up time (and tried to force some initially anyway). Very unscientific, but uncap1was consistently slower than uncap2and uncap3by about 40%. Not that it matters, we're talking a difference of 400ms across a million iterations on an Intel Atom processor. :-)

我在各种测试中混淆了顺序(移动它们并重新编译)以避免加速时间问题(并试图在最初强制一些)。非常不科学的,但uncap1始终比慢uncap2uncap3约40%。这并不重要,我们说的是英特尔凌动处理器上百万次迭代的差异为 400 毫秒。:-)

So: I'd go with your simple, straightforward code, wrapped up in a utility function.

所以:我会使用你的简单、直接的代码,包含在一个实用程序函数中。

回答by Russell Leggett

Watch out for any of the character functions in strings. Because of unicode, it is not always a 1 to 1 mapping. Stick to string based methods unless char is really what you want. As others have suggested, there are string utils out there, but even if you don't want to use them for your project, just make one yourself as you work. The worst thing you can do is to make a special function for lowercase and hide it in a class and then use the same code slightly differently in 12 different places. Put it somewhere it can easily be shared.

注意字符串中的任何字符函数。由于 unicode,它并不总是 1 对 1 的映射。坚持基于字符串的方法,除非 char 真的是你想要的。正如其他人所建议的那样,那里有字符串实用程序,但即使您不想在您的项目中使用它们,也只需在工作时自己制作一个。你能做的最糟糕的事情是为小写写一个特殊的函数并将它隐藏在一个类中,然后在 12 个不同的地方使用相同的代码。把它放在可以轻松共享的地方。

回答by Marcus Leon

Use StringBuffer:

使用StringBuffer

buffer.setCharAt(0, Character.toLowerCase(buffer.charAt(0)));