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