Цикл в строке для поиска символов Юникода занимает слишком много времени

Я создаю настраиваемое поле, в котором я хочу заменить некоторые символы в кодировке Юникод на изображения. Это как делать смайлики для устройства 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 ответа

Решение

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

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

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
    }
}

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

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

Что требует времени, так это конкатенация строк.

Строки неизменны в 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();

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

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

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

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

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

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

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