Char Array против строки:что лучше хранить набор букв
-
03-07-2019 - |
Вопрос
Мне нужно хранить в константном классе 4 буквы кода.Я могу сделать:
static final String CODE_LETTERS = "TRWAG";
или
static final char[] CODE_LETTERS = {'T', 'R', 'W', 'A', 'G'};
После этого я могу получить одного из этих персонажей двумя способами:
final char codeLetter = CODE_LETTERS.charAt(index);
или
final char codeLetter = CODE_LETTERS[index];
какой лучший способ?Пожалуйста, примите во внимание коррекцию, производительность и т. д.
Решение
Производительность в данном случае не имеет значения.Если оно действительно должно быть постоянным, вы не можете использовать char[]
подход.Учитывать:
public class Test
{
static final char[] CODE_LETTERS = {'T', 'R', 'W', 'A', 'G'};
public static void main(String[] args) throws Exception
{
System.out.println(CODE_LETTERS[0]); // T
CODE_LETTERS[0] = 'x';
System.out.println(CODE_LETTERS[0]); // x
}
}
Другие советы
Ни то, ни другое неверно, но поскольку вы будете иметь дело с char
индивидуально, я бы лично использовал char []
.Тем не менее, влияние, которое это окажет на производительность, будет незначительным, если даже измеримым.
Если вы не собираетесь извлекать персонажа несколько миллионов раз подряд, вам не нужно беспокоиться о производительности.
Это почти наверняка преждевременная оптимизация.Все, что вы сохраняете в производительности с помощью массива символов, может быть потеряно для чтения, если вам нужно передать это другим методам, поскольку более канонично принять String
а не char[]
.
Строки неизменяемы, а char[] — нет.Если вы определяете это как общедоступную «константу» в классе, то String является настоящей константой.
Например, если у вас есть это:
public class MyClass {
public static final char[] CODE_LETTERS = {'h', 'e', 'l', 'l', 'o'};
....
}
Я могу быть хитрым и сделать это:
MyClass.CODE_LETTERS[0] = 'Q';
Бам, я изменил значение твоей «константы».
А final
Ключевое слово влияет только на ссылку на массив, оно не применяется к элементам массива.Я постоянно вижу подобную ошибку Collections.unmodifiableList()
, люди думают, что это защищает их список, но клиентский код по-прежнему может получать доступ к элементам списка и изменять их.
Итак, чтобы ответить на ваш вопрос, используйте метод String.
Значение String
действительно соответствует набору char
.Так char[]
как реализация, хотя и не означает набор, не добавит дополнительного значения String
.OTOH, вы можете найти полезный метод в String
.С третьей стороны, java.util.Массивы также есть полезные методы, такие как [binarySearch][2].
Возможно, вы хотите ввести абстракцию для набора char
которые могут варьировать реализацию между использованием String
как самое простое, что могло бы сработать, линейное сканирование char[]
(быстро, если не сканировать очень далеко), двоичный поиск, установка битов.разреженный набор битов, хеширование, фильтрация потока и т. д.
[2]: http://java.sun.com/javase/6/docs/api/java/util/Arrays.html#binarySearch(char[], интервал, интервал, символ)
Поскольку строка использует char[] для хранения ваших букв, истинный ответ: char[] работает быстрее.Если вы сомневаетесь, посмотрите на исходный код: в String нет никакой магии, он просто использует примитивы, такие как int и char[], как и любой другой класс.
Вас действительно не должна волновать такая тривиальная вещь, как эта.В программе происходит гораздо больше, например, беспокойство о том, работает ли одна строка быстрее, чем использование массива символов.
Единственный раз, когда вы увидите разницу в производительности между строкой и массивом символов, это будет под профилировщиком, и то только потому, что профилировщик будет делать неправильные действия.Современная JVMS (JDk 6+) будет генерировать один и тот же код для двух доступов, как только JVM решит, что это достаточно важно для оптимизации.
Однако, чтобы ответить на ваш вопрос;Если вы используете Java 5, используйте перечисления, если вы используете что-то до Java5, используйте Шаблон перечисления Java.
Это сделает ваш код более читабельным, так как вам не нужно будет где-то отслеживать смещения, вы можете просто использовать перечисление.Кроме того, это воля будьте быстрее, так как вы сможете сделать что-то вроде:
final char codeLetter = enum.getCodeLetter();
Похоже, вам следует рассмотреть возможность использования перечисление.Видеть Типы перечислений
Забавно, я только что написал запись в блоге об этом вчера.Вам нужен специализированный класс, обернутый вокруг char[].Мой Персонажи class — это легкий способ сохранить неизменяемый набор символов и предоставляет высокоэффективные методы для таких задач, как поиск.Это открытый исходный код.