Каков наилучший способ получить первую букву из строки в Java, возвращенную в виде строки длиной 1?
Предположим следующее:
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);
}
}
}
}
Ответы
Ответ 1
Производительность wise 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
Ответ 2
Короче говоря, это, вероятно, не имеет значения. Используйте то, что вы считаете самым приятным.
Более длинный ответ, используя JDK Oracle Java 7 специально, поскольку это не определено в JLS:
String.valueOf
или Character.toString
работают одинаково, поэтому используйте то, что вам кажется более приятным. Фактически, Character.toString
просто вызывает String.valueOf
(источник).
Итак, вопрос в том, должен ли вы использовать один из них или String.substring
. И здесь это не имеет большого значения. String.substring
использует исходную строку char[]
и поэтому выделяет один объект меньше, чем String.valueOf
. Это также препятствует тому, чтобы исходная строка была GC'ed до тех пор, пока односимвольная строка не будет доступна для GC (которая может быть утечкой памяти), но в вашем примере оба они будут доступны для GC после каждой итерации, Не важно. Вы также несете выделение, которое вы сохраняете, - a char[1]
дешево выделять, а краткосрочные объекты (так как строка 1 char) тоже дешевы для GC.
Если у вас достаточно большой набор данных, чтобы три были измеримы, substring
, вероятно, даст небольшое преимущество. Вроде, очень слабо. Но что "если... измеримое" содержит реальный ключ к этому ответу: почему бы вам просто не попробовать все три и измерить, какой из них самый быстрый?
Ответ 3
String whole = "something";
String first = whole.substring(0, 1);
System.out.println(first);
Ответ 4
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 |
+----------------------------------------------------------------------+
Ответ 5
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)+".");
}
}
}