String против StringBuffer
Когда дело касается строковых, используете ли вы String или StringBuffer для хранения строковых данных, может оказать значительный эффект на вашу общую производительность. Сегодня мы рассмотрим оба класса - String и StringBuffer и определим те ситуации, в которых вместо String должен использоваться StringBuffer.
Объект String просто хранит массив символов и предоставляет методы для исполнения операций на этом массиве. Объект String - также единственный объект, который перегружает оператор конкатенации "+". Это позволяет строковым быть созданными конкатенацией одного или нескольких объектов String.
Например:
String fname = "John"; String lname = "Smith"; String fullname = fname + lname;
Однако строки - неизменные значения, однажды созданные они не могут изменяться. Всякий раз, когда Вы переназначаете значение строковой переменной, вы на самом деле создаете другой объект String и сообщаете JVM, что нужно использовать недавно созданный объект String как (placeholder) для переменной.
Например:
String fname = "John"; /* создан новый объект String Старый объект, ожидающий сборку "мусора" */ fname = "Jack";
Рассмотрим случай, когда строковая переменная должна измениться несколько раз. Каждый раз, когда значение этой строковой переменной изменяется, должен быть создан новый объект String. Это приведет к созданию нескольких объектов String в памяти, ожидающим сборку "мусора". Не упоминая даже о дополнительной нагрузке на ЦП при создании этих новый объектов.
Например:
int i; String contents = null; for(i = 0; i < 10; i++) { contents += "hello world\n"; } /* вывод содержимого на экран */ System.out.println(contents);
Вышеупомянутый код создал бы, 10 отдельных объектов String, 9 из которых постоянно находятся в памяти, ожидая сборку "мусора". Большую эффективность даст обработка с помощью объекта StringBuffer.
Объект StringBuffer тоже хранит массив символов, но с некоторыми тонкими различиями.
- В нем не перегружен метод конкатенации "+".
- Его содержимое может быть изменено без создания новых экземпляров объекта StringBuffer.
Изменение кода, представленного выше, чтобы воспользоваться преимуществом объекта StringBuffer, требует только нескольких простых изменений.
Пример:
int i; StringBuffer contents = new StringBuffer(); for(i = 0; i < 10; i++) { contents.append("hello world\n"); } /* вывод содержимого на экран */ System.out.println(contents.toString());
Применяя объект StringBuffer, только один объект используется на протяжении действия цикла. Повышение производительности может быть неочевидно в таком малом цикле, как представленный выше. Однако попробуйте проделать это с объектом String, когда вы предполагаете изменять его сотни раз, и вы начнете обращать внимание на разницу.