从Java中的字符串中获取第一个字母的最佳方法是什么,以长度为1的字符串返回?

Adr*_*rie 67 java string

假设如下:

String example      = "something";
String firstLetter  = "";
Run Code Online (Sandbox Code Playgroud)

是否存在差异,需要注意以下firstLetter可能影响绩效的分配方式; 哪个最好,为什么?

firstLetter = String.valueOf(example.charAt(0));
firstLetter = Character.toString(example.charAt(0));
firstLetter = example.substring(0, 1);
Run Code Online (Sandbox Code Playgroud)

第一个字母作为a返回的原因String是它在Hadoop中运行,并且需要分配给Text类型的字符串,firstLetter将作为a keymap()方法输出,例如:

public class FirstLetterMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    String line = new String();
    Text firstLetter = new Text();
    IntWritable wordLength = new IntWritable();

    @Override
    public void map(LongWritable key, Text value, Context context)
            throws IOException, InterruptedException {

        line = value.toString();

        for (String word : line.split("\\W+")){
            if (word.length() > 0) {

                // ---------------------------------------------
                // firstLetter assignment
                firstLetter.set(String.valueOf(word.charAt(0)).toLowerCase());
                // ---------------------------------------------

                wordLength.set(word.length());
                context.write(firstLetter, wordLength);
            }
        }
  }
}
Run Code Online (Sandbox Code Playgroud)

Ank*_*thi 107

性能明智substring(0, 1)更好,如下所示:

    String example = "something";
    String firstLetter  = "";

    long l=System.nanoTime();
    firstLetter = String.valueOf(example.charAt(0));
    System.out.println("String.valueOf: "+ (System.nanoTime()-l));

    l=System.nanoTime();
    firstLetter = Character.toString(example.charAt(0));
    System.out.println("Character.toString: "+ (System.nanoTime()-l));

    l=System.nanoTime();
    firstLetter = example.substring(0, 1);
    System.out.println("substring: "+ (System.nanoTime()-l));
Run Code Online (Sandbox Code Playgroud)

输出:

String.valueOf: 38553
Character.toString: 30451
substring: 8660
Run Code Online (Sandbox Code Playgroud)

  • 这是事后的方式,但我觉得更合适的计时方法会涉及多次执行此测试,而不是上面的代码暗示的一次.请在gist.github.com/micahjsmith/c7c9d31b342c115aef90上查看我的测试代码.在GNU/Linux上运行Java 1.7,我发现上面显示的三种方法没有区别,如果有的话,String.valueOf具有我所见的最佳性能.(虽然跑步之间存在一些差异.)这使我倾向于相信下面的@yshavit对这个问题有更适用的回应. (15认同)

ysh*_*vit 13

长话短说,这可能没关系.使用您认为最好的选择.

更长的答案,特别是使用Oracle的Java 7 JDK,因为这不是在JLS中定义的:

String.valueOfCharacter.toString以相同的方式工作,所以使用你觉得好看的任何一个.实际上,Character.toString只需调用String.valueOf().

所以问题是,你应该使用其中之一还是String.substring.这里再次没关系.String.substring使用原始字符串char[],因此分配一个少于的对象String.valueOf.这也可以防止原始字符串被GC控制,直到单字符字符串可用于GC(可能是内存泄漏),但在您的示例中,它们在每次迭代后都可用于GC,因此不会没关系 您保存的分配也无关紧要 - char[1]分配起来很便宜,而短期对象(因为单字符串将是)也很便宜.

如果你有足够大的数据集,三者甚至可以测量,substring可能会略有优势.就像,非常轻微.但是"如果......可衡量的"包含了这个答案的真正关键:你为什么不试试这三个并测量哪一个最快?


小智 6

String whole = "something";
String first = whole.substring(0, 1);
System.out.println(first);
Run Code Online (Sandbox Code Playgroud)