Чего самый легкий/лучший/больше всего корректный путь состоит в том, чтобы выполнить итерации через символы строки в Java?

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
307
задан jjnguy 22 April 2011 в 05:50
поделиться

8 ответов

Я использую для цикла для итерации строки и использования charAt(), чтобы заставить каждый символ исследовать его. Так как Строка реализована с массивом, charAt(), метод является постоянной операцией времени.

String s = "...stuff...";

for (int i = 0; i < s.length(); i++){
    char c = s.charAt(i);        
    //Process char
}

Это - то, что я сделал бы. Это кажется самым легким мне.

, Насколько правильность идет, я не полагаю, что это существует здесь. Это - все на основе Вашего персонального стиля.

325
ответ дан Thirumalai Parthasarathi 23 November 2019 в 01:18
поделиться

StringTokenizer является полностью неподходящим к задаче повреждения строки в ее отдельные символы. С String#split() можно сделать это легко при помощи regex, который ничему не соответствует, например:

String[] theChars = str.split("|");

, Но StringTokenizer не использует regexes, и нет никакой строки разделителя, можно определить, что это не будет соответствовать ничему между символами. Там один милый небольшой взлом, который можно использовать для выполнения того же самого: используйте саму строку в качестве строки разделителя (делающий каждый символ в нем разделитель) и имейте его, возвращают разделители:

StringTokenizer st = new StringTokenizer(str, str, true);

Однако я только упоминаю эти опции в целях отклонения их. Оба метода повреждают исходную строку в одну символьную строку вместо символьных примитивов, и оба включают много издержек в форме создания объекта и обработки строк. Сравните это с вызовом charAt () в для цикла, который не подвергается фактически никаким издержкам.

0
ответ дан Alan Moore 23 November 2019 в 01:18
поделиться

Я не использовал бы StringTokenizer, поскольку это - один из классов в JDK, это - наследие.

javadoc говорит:

StringTokenizer класс прежней версии, который сохраняется по причинам совместимости, хотя ее использованию препятствуют в новом коде. Рекомендуется, чтобы любой ищущий эту функциональность использовал метод разделения String или java.util.regex пакет вместо этого.

3
ответ дан Alan 23 November 2019 в 01:18
поделиться

См. Учебные руководства по Java: Строки .

public class StringDemo {
    public static void main(String[] args) {
        String palindrome = "Dot saw I was Tod";
        int len = palindrome.length();
        char[] tempCharArray = new char[len];
        char[] charArray = new char[len];

        // put original string in an array of chars
        for (int i = 0; i < len; i++) {
            tempCharArray[i] = palindrome.charAt(i);
        } 

        // reverse array of chars
        for (int j = 0; j < len; j++) {
            charArray[j] = tempCharArray[len - 1 - j];
        }

        String reversePalindrome =  new String(charArray);
        System.out.println(reversePalindrome);
    }
}

Помещенный длина в int len и использование for цикл.

0
ответ дан Eugene Yokota 23 November 2019 в 01:18
поделиться

Существуют некоторые специализированные классы для этого:

import java.text.*;

final CharacterIterator it = new StringCharacterIterator(s);
for(char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
   // process c
   ...
}
20
ответ дан Bruno De Fraine 23 November 2019 в 01:18
поделиться

Я соглашаюсь, что StringTokenizer является излишеством здесь. На самом деле я испытал предложения выше и не торопился.

Мой тест был довольно прост: создайте StringBuilder приблизительно с миллионом символов, преобразуйте его в Строку и пересеките каждого из них с charAt () / после преобразования в массив символов / с CharacterIterator тысячу раз (конечно, удостоверяющийся делать что-то на строке, таким образом, компилятор не может оптимизировать далеко целый цикл:-)).

результат на моем Powerbook на 2,6 ГГц (это - Mac:-)), и JDK 1.5:

  • Тест 1: charAt + Строка-> 3 138 Тестов msec
  • 2: Строка, преобразованная в массив-> 9 568 Тестов msec
  • 3: StringBuilder charAt-> 3 536 Тестов msec
  • 4: CharacterIterator и Строка-> 12 151 msec

Как результаты существенно отличается, самый простой путь также, кажется, самый быстрый. Интересно, charAt () StringBuilder, кажется, немного медленнее, чем тот Строки.

BTW я предлагаю не использовать CharacterIterator, поскольку я считаю его злоупотребление '\uFFFF' символом как "конец повторения" действительно ужасный взлом. В больших проектах всегда существует два парня, которые используют тот же вид взлома в двух различных целях и катастрофических отказах кода действительно загадочно.

Вот один из тестов:

    int count = 1000;
    ...

    System.out.println("Test 1: charAt + String");
    long t = System.currentTimeMillis();
    int sum=0;
    for (int i=0; i<count; i++) {
        int len = str.length();
        for (int j=0; j<len; j++) {
            if (str.charAt(j) == 'b')
                sum = sum + 1;
        }
    }
    t = System.currentTimeMillis()-t;
    System.out.println("result: "+ sum + " after " + t + "msec");
24
ответ дан 23 November 2019 в 01:18
поделиться

Обратите внимание, что большинство других методов, описанных здесь, ломается, если Вы имеете дело с символами за пределами BMP (Unicode Основная Многоязычная Плоскость ), т.е. кодовые точки , которые являются за пределами диапазона u0000-uFFFF. Это будет только редко происходить, так как кодовые точки вне этого главным образом присвоены мертвым языкам. Но существуют некоторые полезные символы вне этого, например, некоторые кодовые точки, используемые для математической нотации, и некоторые раньше кодировали имена собственные на китайском языке.

В этом случае Ваш код будет:

String str = "....";
int offset = 0, strLen = str.length();
while (offset < strLen) {
  int curChar = str.codePointAt(offset);
  offset += Character.charCount(curChar);
  // do something with curChar
}

Character.charCount(int) метод требует Java 5 +.

Источник: http://mindprod.com/jgloss/codepoint.html

88
ответ дан Buhake Sindi 23 November 2019 в 01:18
поделиться

Две опции

for(int i = 0, n = s.length() ; i < n ; i++) { 
    char c = s.charAt(i); 
}

или

for(char c : s.toCharArray()) {
    // process c
}

первое, вероятно, быстрее, тогда 2-й, вероятно, более читаемо.

195
ответ дан jjnguy 23 November 2019 в 01:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: