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

时间:2013-08-13 05:16:02

标签: java string

假设如下:

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

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

firstLetter = String.valueOf(example.charAt(0));
firstLetter = Character.toString(example.charAt(0));
firstLetter = example.substring(0, 1);

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

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);
            }
        }
  }
}

5 个答案:

答案 0 :(得分:104)

明智的表现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));

<强>输出:

String.valueOf: 38553
Character.toString: 30451
substring: 8660

答案 1 :(得分:13)

长话短说,这可能并不重要。使用你认为最好的那个。

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

String.valueOfCharacter.toString以相同的方式工作,因此请使用您认为更好的效果。事实上,Character.toString只需拨打String.valueOfsource)。

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

如果你有足够大的数据集,这三个数据集甚至可以测量,substring可能会给出轻微的边缘。就像,非常轻微。但那......&#34;如果......可衡量的&#34;包含了这个答案的真正关键:为什么你不试试这三个并测量哪一个最快?

答案 2 :(得分:5)

String whole = "something";
String first = whole.substring(0, 1);
System.out.println(first);

答案 3 :(得分:1)

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;

import java.util.concurrent.TimeUnit;

@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 1)
@Fork(value = 1)
@Measurement(iterations = 5, time = 1)
public class StringFirstCharBenchmark {

    private String source;

    @Setup
    public void init() {
        source = "MALE";
    }

    @Benchmark
    public String substring() {
        return source.substring(0, 1);
    }

    @Benchmark
    public String indexOf() {
        return String.valueOf(source.indexOf(0));
    }
}

结果:

+----------------------------------------------------------------------+
| Benchmark                           Mode  Cnt   Score   Error  Units |
+----------------------------------------------------------------------+
| StringFirstCharBenchmark.indexOf    avgt    5  23.777 ? 5.788  ns/op |
| StringFirstCharBenchmark.substring  avgt    5  11.305 ? 1.411  ns/op |
+----------------------------------------------------------------------+

答案 4 :(得分:-4)

import java.io.*;
class Initials
{
   public static void main(String args[])throws IOException
   {
      BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
      String s;
      char x;
      int l;
      System.out.print("Enter any sentence: ");
      s=br.readLine();
      s = " " + s; //adding a space infront of the inputted sentence or a name
      s = s.toUpperCase(); //converting the sentence into Upper Case (Capital Letters)
      l = s.length(); //finding the length of the sentence</span>
      System.out.print("Output = ");

      for(int i=0;i<l;i++)
      {
         x = s.charAt(i); //taking out one character at a time from the sentence
         if(x == ' ') //if the character is a space, printing the next Character along with a fullstop
          System.out.print(s.charAt(i+1)+".");
      }
    }
}