Java String.split передается в предварительно скомпилированном регулярном выражении по соображениям производительности

Как говорится в этом вопросе, приведен следующий код:

public class Foo
{
   public static void main(String[] args)
   {  
         String test = "Cats go meow";  
         String[] tokens = test.split(" ");
   }
}

можно предварительно скомпилировать это регулярное выражение в функции расщепления по строкам:

public class Foo
{  
   Pattern pattern = Pattern.compile(" ");
   public static void main(String[] args)
   {  
         String test = "Cats go meow";  
         String[] tokens = test.split(pattern);
   }
}

Ответ 1

Да, это возможно. Кроме того, make pattern static, поэтому статический метод main может получить к нему доступ.

public class Foo
{  
   private static Pattern pattern = Pattern.compile(" ");
   public static void main(String[] args)
   {  
         String test = "Cats go meow";  
         String[] tokens = pattern.split(test);
   }
}

В соответствии с docs для метода split в String вы можете использовать String split или Pattern split, но String split компилирует a pattern и вызывает его метод split, поэтому используйте pattern, чтобы предварительно скомпилировать регулярное выражение.

Ответ 2

public class Foo
{  
   private static final Pattern pattern = Pattern.compile(" ");
   public static void main(String[] args)
   {  
         String test = "Cats go meow";  
         String[] tokens = pattern.split(test);
   }
}

Ответ 3

Используйте Pattern.split() вместо:

String[] tokens = pattern.split(test);

Ответ 4

Нет - я думаю, что это была бы плохая идея!

Внимательно изучая исходный код split-метода - существует ярлык, реализованный в случае, если строка имеет только один символ (и не содержит специальный символ регулярного выражения)

public String[] split(String regex, int limit) {
    /* fastpath if the regex is a
     (1)one-char String and this character is not one of the
        RegEx meta characters ".$|()[{^?*+\\", or
     (2)two-char String and the first char is the backslash and
        the second is not the ascii digit or ascii letter.
     */
    char ch = 0;
    if (((regex.value.length == 1 &&
         ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||

so-split ("") должен быть намного быстрее.

С другой стороны, при использовании регулярных выражений всегда полезно сделать их статичными конечными членами.

изменить:

Исходный код JDK1.7 и OpenJDK 7 кажется идентичным для String.split - посмотрите сами: Строки 2312ff.

Итак - для более сложных шаблонов (например, для одного или нескольких пространств):

   static final Pattern pSpaces = Pattern.compile("[ ]+");