Цикл в строке для поиска символов Юникода занимает слишком много времени - PullRequest
1 голос
/ 28 сентября 2011

Я создаю настраиваемое поле, в котором я хочу заменить некоторые символы Юникода изображениями. Это как делать смайлики для устройства BlackBerry. Что ж, у меня проблема с зацикливанием символов в поле редактирования и заменой символов Юникода изображениями. Когда текст становится слишком длинным, цикл занимает слишком много времени.

Мой код выглядит следующим образом:

String aabb = "";
char[] chara = this.getText().toCharArray();
for (int i = loc; i < chara.length; i ++) {
   Character cc = new Character(chara[i]);
   aabb += cc.toString();
   if (unicodeCaracter) {
       //Get the location
       //draw the image in the appropriate X and Y
   }
}

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

Как найти символы Unicode в тексте без необходимости каждый раз их зацикливать? Неужели я пропустил их иначе, чем этот?

Мне нужна помощь с этим вопросом. Заранее спасибо

Ответы [ 4 ]

8 голосов
/ 28 сентября 2011

Итак, вы создаете новый символ и новую строку в каждой итерации цикла, и , преобразуя строку в массив символов для начала.Вы также используете конкатенацию строк в цикле, а не StringBuffer.Все это будет ухудшать производительность.

Не очевидно, что вы подразумеваете здесь под "символами Юникода" - все символы в Java являются символами Юникода.Я подозреваю, что вы действительно хотите что-то вроде:

String text = this.getText();
StringBuffer buffer = new StringBuffer(text.length());
for (int i = 0; i < text.length(); i++) {
    char c = text.charAt(i);
    buffer.append(c);
    if (c > 127) { // Or whatever
        // Take some action
    }
}

Я предполагаю, что "предпринять какое-то действие" в некотором отношении изменит буфер, иначе буфер, конечно, не имеет смысла ... но в принципе это вероятнобыть сортировкой изменений, которые вы хотите.

Конкатенация строк в цикле - это особенно плохая идея - см. мою статью для получения более подробной информации.

4 голосов
/ 28 сентября 2011

Требуется время для конкатенации строк.

Строки являются неизменяемыми в Java. Каждый раз, когда вы делаете

aabb += cc.toString();

Вы создаете новый объект String, содержащий все символы предыдущего, которые должны быть собраны мусором, плюс новые. Используйте StringBuilder для построения вашей строки:

StringBuilder builder = new StringBuilder(this.getText().length() + 100); // size estimation
char[] chara = this.getText().toCharArray();
for (int i = loc; i < chara.length; i++) {
   builder.append(chara[i]);
   if (unicodeCaracter) {
       //Get the location
       //draw the image in the appropriate X and Y
   }
}
String aabb = builder.toString();
0 голосов
/ 28 сентября 2011

Наиболее важные улучшения производительности уже были заявлены, но обратный цикл также поможет в приложениях BlackBerry.

Советы по программированию: общие советы по кодированию

0 голосов
/ 28 сентября 2011

Ну, кроме ускорения цикла, вы также можете попытаться минимизировать рабочую нагрузку.

Если пользователь добавляет текст, вы можете сохранить последнюю позицию, которую вы сканировали ранее, и начать отсюда.

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

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

...