从 Java 中的字符串中获取第一个字母的最佳方法是什么,以长度为 1 的字符串形式返回?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18201191/
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
What is the best way to get the first letter from a string in Java, returned as a string of length 1?
提问by Adrian Torrie
Assume the following:
假设如下:
String example = "something";
String firstLetter = "";
Are there differences to be aware of with the following ways of assigning firstLetter
that could impact performance; which would be best, and why?
是否存在以下firstLetter
可能影响性能的分配方式的差异需要注意;哪个最好,为什么?
firstLetter = String.valueOf(example.charAt(0));
firstLetter = Character.toString(example.charAt(0));
firstLetter = example.substring(0, 1);
The reason the first letter is being returned as a String
is that this is being run in Hadoop, and a string is required to assign to a Text
type, firstLetter
will be output as a key
from a map()
method, for example:
第一个字母作为 a 返回的原因String
是它正在 Hadoop 中运行,并且需要一个字符串来分配给一个Text
类型,将从一个方法中firstLetter
作为 a 输出,例如: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);
}
}
}
}
采纳答案by Ankur Lathi
Performance wise substring(0, 1)
is better as found by following:
性能方面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));
Output:
输出:
String.valueOf: 38553
Character.toString: 30451
substring: 8660
回答by yshavit
Long story short, it probably doesn't matter. Use whichever you think looks nicest.
长话短说,这可能无关紧要。使用您认为最好看的那个。
Longer answer, using Oracle's Java 7 JDK specifically, since this isn't defined at the JLS:
更长的答案,特别是使用 Oracle 的 Java 7 JDK,因为这不是在 JLS 中定义的:
String.valueOf
or Character.toString
work the same way, so use whichever you feel looks nicer. In fact, Character.toString
simply calls String.valueOf
(source).
String.valueOf
或者Character.toString
以同样的方式工作,所以使用你觉得更好看的那个。实际上,Character.toString
只需调用String.valueOf
( source)。
So the question is, should you use one of those or String.substring
. Here again it doesn't matter much. String.substring
uses the original string's char[]
and so allocates one object fewer than String.valueOf
. This also prevents the original string from being GC'ed until the one-character string is available for GC (which can be a memory leak), but in your example, they'll both be available for GC after each iteration, so that doesn't matter. The allocation you save also doesn't matter -- a char[1]
is cheap to allocate, and short-lived objects (as the one-char string will be) are cheap to GC, too.
所以问题是,你应该使用其中之一还是String.substring
. 这里又没有太大关系。String.substring
使用原始字符串char[]
,因此分配的对象少于String.valueOf
. 这也可以防止原始字符串被 GC 处理,直到一个字符的字符串可用于 GC(这可能是内存泄漏),但在您的示例中,它们在每次迭代后都可用于 GC,因此不会没关系。您保存的分配也无关紧要—— achar[1]
分配起来很便宜,而且短期对象(如单字符字符串一样)对于 GC 来说也很便宜。
If you have a large enough data set that the three are even measurable, substring
will probably give a slightedge. Like, really slight. But that "if... measurable" contains the real key to this answer: why don't you just try all three and measure which one is fastest?
如果您有足够大的数据集,这三个甚至可以测量,substring
则可能会略有优势。喜欢,真的很轻微。但是“如果……可测量”包含了这个答案的真正关键:为什么不尝试所有三个并测量哪个最快?
回答by rohan
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
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) + ".");
}
}
}
回答by MIk.13
String whole = "something";
String first = whole.substring(0, 1);
System.out.println(first);
回答by Nikita
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 |
+----------------------------------------------------------------------+