What is the best way to get the first letter of a string in Java returned as a string of length 1?

Assume the following:

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

Are there any differences that should be considered with the following methods for assigning firstLetter , which can affect performance; what would be better and why?

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

The reason the first letter is returned as String is because it is executed in Hadoop and a string is required to be assigned to the Text type, firstLetter will be displayed as key from the map() method, for example:

 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); } } } } 
+65
java string
Aug 13 '13 at 5:16
source share
5 answers

The performance of wise substring(0, 1) better than below:

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

Output:

 String.valueOf: 38553 Character.toString: 30451 substring: 8660 
+103
Aug 13 '13 at 6:46
source share

In short, it probably doesn't matter. Use what you find most enjoyable.

Longer answer using the Oracle Java 7 JDK specifically, as this is not defined in JLS:

String.valueOf or Character.toString work the same way, so use whatever seems more pleasant to you. In fact, Character.toString just calls String.valueOf ( source ).

So the question is whether you should use one of them or String.substring . And here it does not really matter. String.substring uses the original string char[] and therefore allocates one object less than String.valueOf . It also prevents the original string from being GC'ed until the single-character string is available to the GC (which may be a memory leak), but in your example both of them will be available to the GC after each iteration, It doesn't matter. You also carry the selection you save - a char[1] cheap to allocate, and short-term objects (since line 1 char) are also cheap for GC.

If you have a sufficiently large dataset so that three are measurable, substring is likely to give a slight advantage. It seems very weak. But what "if ... measurable" contains the real key to this answer: why don't you just try all three and measure which one is the fastest?

+13
Aug 13 '13 at 5:54 on
source share
 String whole = "something"; String first = whole.substring(0, 1); System.out.println(first); 
+5
Jul 04 '17 at 18:53 on
source share
 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)); } } 

Results:

 +----------------------------------------------------------------------+ | 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 | +----------------------------------------------------------------------+ 
0
May 21 '19 at 13:37
source share
 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)+"."); } } } 
-four
Feb 27 '15 at 9:18
source share



All Articles