String.lastIndexOf () есть ли разница между символом и строкой с одним символом?

Просто интересно, знал ли кто-нибудь в голову, есть ли большая разница в том, чтобы сделать следующее:

String wibble = "<blah> blah blah </blah>.... <wibble> blah wibble blah </wibble> some more test here";

int i = wibble.lastIndexOf(">");
int j = wibble.lastIndexOf('>');

Не беспокойтесь об этом, это не будет иметь большого значения. Выберите тот, который более понятен

Pyrolistical 23.01.2009 00:52
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
5
1
2 306
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

С точки зрения производительности может быть небольшая разница. Для поиска одного символа быстрее или равнозначнее использовать char вместо String.

У строки есть дополнительные накладные расходы, которые требуются независимо от ее длины (если у вас нет действительно умного компилятора, который все равно оптимизирует односимвольные строковые литералы в символьные константы :)), поэтому вам следует предпочесть версию char, если вы ищете только одиночные символы. Это не плохая оптимизация, поскольку в любом случае она читаемо эквивалентна.

Вы действительно можете посмотреть исходный код класса String. Кажется, что lastIndex (char) и lastIndex (String) были написаны отдельно. Также должны быть накладные расходы с классом String. Таким образом, версия char может быть немного быстрее, но я сомневаюсь, что будет случай с какой-либо значительной разницей в производительности.

http://www.docjar.com/html/api/java/lang/String.java.html

Там, где нет разницы в удобочитаемости (как в этом случае), лучше выбрать версию, которая ищет только символ. У lastIndexOf меньше работы - проще найти один элемент в списке, чем найти подсписок (что, по сути, и делает поиск строки).

Ключевым моментом здесь является удобочитаемость. Неприемлемым микрооптом, на мой взгляд, был бы if (needle.length() == 1) { i = haystack.lastIndexOf(needle.charAt[0]); } else {....

Mark Peters 20.08.2010 18:40

может быть (по общему признанию слабый) аргумент для использования строковой версии для удобства обслуживания, если строка поиска может быть длиной более одного символа в будущем, т. е. меньше усилий переходить с ">" на "/>", если подобное изменение необходимо.

Kip 20.08.2010 21:33

@ Кип: Это достаточно легко изменить, когда вам это нужно, ИМО.

Jon Skeet 20.08.2010 22:14
Ответ принят как подходящий

Мнения отличные, но данные лучше. Я написал быстрый тест:

Тестовый код

public static void main(String[] args)
{
  System.out.println("Starting perfo test");

  final long NUM_TESTS = 100000000L;

  String wibble = "<blah> blah blah </blah>.... <wibble>"
                + " blah wibble blah </wibble> some more test here";
  int x = -1;
  Stopwatch sw = new Stopwatch();

  System.out.println("--perfo test with " + NUM_TESTS + " iterations--");

  sw.start();
  for(long i = 0; i < NUM_TESTS; i++)
    x = wibble.lastIndexOf(">");
  sw.stop();
  System.out.println("String first pass: " + sw + " seconds");

  sw.start();
  for(long i = 0; i < NUM_TESTS; i++)
    x = wibble.lastIndexOf('>');
  sw.stop();
  System.out.println("Char first pass: " + sw + " seconds");

  sw.start();
  for(long i = 0; i < NUM_TESTS; i++)
    x = wibble.lastIndexOf('>');
  sw.stop();
  System.out.println("Char second pass: " + sw + " seconds");

  sw.start();
  for(long i = 0; i < NUM_TESTS; i++)
    x = wibble.lastIndexOf(">");
  sw.stop();
  System.out.println("String second pass: " + sw + " seconds");

  //Compiler warning said x was never read locally.. this is to
  //ensure the compiler doesn't optimize "x" away..
  System.out.println(x); 
}

Выход

Starting perfo test
--perfo test with 100000000 iterations--
String first pass: 8.750 seconds
Char first pass: 6.500 seconds
Char second pass: 6.437 seconds
String second pass: 8.610 seconds
63

Заключение

Версия с символом примерно на 25% быстрее, но обе версии выполняются очень быстро, поэтому она, вероятно, никогда не станет узким местом в вашем коде.

Другие вопросы по теме