Char Array vs String: что лучше для хранения набора букв - PullRequest
7 голосов
/ 29 апреля 2009

Мне нужно хранить в константе класса 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];

как лучше? Пожалуйста, помните об исправлении, производительности и т. Д.

Ответы [ 10 ]

8 голосов
/ 29 апреля 2009

Ни то, ни другое неверно, но, поскольку вы будете иметь дело с char по отдельности, я бы лично использовал char []. Тем не менее, влияние, которое это окажет на производительность, будет незначительным, если даже измеримым.

7 голосов
/ 29 апреля 2009

Производительность не имеет значения в этом случае. Если он действительно должен быть постоянным, вы не можете использовать подход 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
  }
}
6 голосов
/ 29 апреля 2009

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

5 голосов
/ 06 мая 2009

Строки являются неизменяемыми, char [] - нет. Если вы определяете это как общедоступную «константу» в классе, тогда String является реальной константой.

Например, если у вас есть это:

public class MyClass { 
    public static final char[] CODE_LETTERS = {'h', 'e', 'l', 'l', 'o'};
    ....
}

Я могу быть подлым и сделать это:

MyClass.CODE_LETTERS[0] = 'Q';

Бэм, я изменил значение твоей "константы".

Ключевое слово final влияет только на ссылку на массив, оно не применяется к элементам массива. Я все время вижу похожую ошибку с Collections.unmodifiableList(), люди думают, что это защищает их список, но клиентский код все еще может получить доступ и изменить элементы списка.

Итак, чтобы ответить на ваш вопрос, используйте строку.

5 голосов
/ 29 апреля 2009

Это почти наверняка преждевременная оптимизация. Все, что вы экономите на производительности, используя массив символов, может быть потеряно в удобочитаемости, если вам нужно передать его другим методам, поскольку более приемлемо принимать String, а не char[].

2 голосов
/ 29 апреля 2009

Значение String действительно соответствует набору char. Таким образом, char[] в качестве реализации, хотя и не имеет значения set, не добавит дополнительного значения String. OTOH, вы можете найти полезный метод в String. С третьей стороны, java.util.Arrays также имеет полезные методы, такие как [binarySearch] [2].

Возможно, что вы хотите сделать, это ввести абстракцию для набора char, который может варьировать реализацию между использованием String в качестве простейшего из возможных, линейное сканирование char[] (быстро, если вы не Сканирование очень далеко), бинарный поиск, бит установлен. установка разреженных битов, хеширование, фильтрация потока и т. д.

[2]: http://java.sun.com/javase/6/docs/api/java/util/Arrays.html#binarySearch(char[], int, int, char)

1 голос
/ 29 апреля 2009

Похоже, вы должны рассмотреть возможность использования enum . См. Типы перечислений

1 голос
/ 29 апреля 2009

Единственный раз, когда вы увидите разницу в производительности между строкой и массивом символов, будет под профилировщиком, и то только потому, что профилировщик будет делать неправильно. Современная JVMS (JDk 6+) сгенерирует один и тот же код для двух обращений, как только JVM решит, что это достаточно горячо для оптимизации.

Чтобы ответить на ваш вопрос, хотя; Если вы используете Java 5, используйте перечисления, если вы используете что-то до Java5, используйте Шаблон перечисления Java .

Это сделает ваш код более читабельным, так как вам не нужно будет где-то отслеживать смещения, вы можете просто использовать перечисление. Кроме того, будет быстрее, так как вы сможете сделать что-то вроде:


  final char codeLetter = enum.getCodeLetter(); 
1 голос
/ 29 апреля 2009

Поскольку строка использует символ [] для хранения ваших букв, истинный ответ: символ [] быстрее. Если вы сомневаетесь, посмотрите на источник, в String нет магии, он просто использует примитивы, такие как int и char [], как и любой другой класс.

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

0 голосов
/ 25 апреля 2011

Забавно, я только что написал запись в блоге об этом вчера. Вам нужен специализированный класс, обернутый вокруг char []. Мой класс Знаки - это легкий способ сохранить неизменный набор символов и предоставляет высокоэффективные методы для таких вещей, как поиск. Это открытый исходный код.

...