Подтвердить что ты не робот

Каков наилучший способ получить первую букву из строки в 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);
            }
        }
  }
}
4b9b3361

Ответ 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)+".");
      }
    }
}