CharSequence VS String в Java? - PullRequest
       11

CharSequence VS String в Java?

398 голосов
/ 26 июня 2009

Программирование в Android, большинство текстовых значений ожидается в CharSequence.

Почему это? В чем выгода и каковы основные последствия использования CharSequence над String?

Каковы основные различия и какие проблемы ожидаются при их использовании и преобразовании из одного в другое?

Ответы [ 9 ]

331 голосов
/ 26 июня 2009

Strings - это CharSequence , так что вы можете просто использовать Strings и не беспокоиться. Android просто пытается помочь, позволяя вам также указывать другие объекты CharSequence, такие как StringBuffers.

44 голосов
/ 01 июля 2015

Эта диаграмма классов может помочь вам увидеть общую картину типов строк в Java 7/8. Я не уверен, что все это присутствует в Android, но общий контекст может оказаться полезным для вас.

Также обратите внимание на комментарии, сделанные к принятому ответу . Интерфейс CharSequence был модернизирован для существующих структур классов, поэтому есть некоторые важные тонкости (equals() & hashCode()). Обратите внимание на различные версии Java (1, 2, 4 и 5), помеченные на классах / интерфейсах - с течением времени они немного изменились. В идеале CharSequence был бы на месте с самого начала, но такова жизнь.

diagram of various string-related classes and interfaces

36 голосов
/ 27 октября 2010

Я считаю, что лучше всего использовать CharSequence. Причина в том, что String реализует CharSequence, поэтому вы можете передавать String в CharSequence, ОДНАКО вы не можете передать CharSequence в String, так как CharSequence не реализует String. Кроме того, в Android метод EditText.getText() возвращает Editable, который также реализует CharSequence и может быть легко передан в один, а не просто в String. CharSequence обрабатывает все!

23 голосов
/ 26 июня 2009

В целом использование интерфейса позволяет варьировать реализацию с минимальным побочным ущербом. Несмотря на то, что java.lang.String очень популярны, возможно, что в определенных контекстах вы захотите использовать другую реализацию. Выстраивая API вокруг CharSequence, а не Strings, код дает возможность сделать это.

8 голосов
/ 15 февраля 2011

Это почти наверняка из соображений производительности. Например, представьте синтаксический анализатор, который проходит через 500k ByteBuffer, содержащий строки.

Существует 3 подхода к возвращению содержимого строки:

  1. Создайте строку [] во время разбора, по одному символу за раз. Это займет заметное количество времени. Мы можем использовать == вместо .equals для сравнения кэшированных ссылок.

  2. Создайте int [] со смещениями во время разбора, а затем динамически соберите String, когда произойдет get (). Каждая строка будет новым объектом, поэтому не нужно кэшировать возвращаемые значения и использовать ==

  3. Создайте CharSequence [] во время разбора. Поскольку никакие новые данные не сохраняются (кроме смещений в байтовом буфере), синтаксический анализ намного ниже, чем # 1. Во время получения нам не нужно создавать строку, поэтому производительность получения равна # 1 (намного лучше, чем # 2), поскольку мы только возвращаем ссылку на существующий объект.

В дополнение к преимуществам обработки, которые вы получаете с помощью CharSequence, вы также уменьшаете объем памяти, не дублируя данные. Например, если у вас есть буфер, содержащий 3 абзаца текста, и вы хотите вернуть либо все 3, либо один абзац, вам нужно 4 строки для представления этого. При использовании CharSequence вам нужен только 1 буфер с данными и 4 экземпляра реализации CharSequence, которая отслеживает начало и длину.

7 голосов
/ 19 ноября 2014

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

EditText t = (EditText )getView(R.id.myEditText); // Contains "OK"
Boolean isFalse = t.getText().equals("OK"); // will always return false.

Сравнение должно быть сделано

("OK").contentEquals(t.GetText()); 
3 голосов
/ 10 ноября 2017

CharSequence

A CharSequence - это интерфейс, а не фактический класс. Интерфейс - это просто набор правил (методов), которые должен содержать класс, если он реализует интерфейс. В Android CharSequence - это зонтик для различных типов текстовых строк. Вот некоторые из распространенных:

  • String (неизменяемый текст без интервалов стиля)
  • StringBuilder (изменяемый текст без интервалов стиля)
  • SpannableString (неизменный текст с интервалами стилей)
  • SpannableStringBuilder (изменяемый текст с интервалами стилей)

(Вы можете узнать больше о различиях между этими здесь .)

Если у вас есть объект CharSequence, то это фактически объект одного из классов, реализующих CharSequence. Например:

CharSequence myString = "hello";
CharSequence mySpannableStringBuilder = new SpannableStringBuilder();

Преимущество общего типа зонта, например CharSequence, заключается в том, что вы можете обрабатывать несколько типов одним методом. Например, если у меня есть метод, который принимает CharSequence в качестве параметра, я мог бы передать String или SpannableStringBuilder, и он обработал бы либо один.

public int getLength(CharSequence text) {
    return text.length();
}

Строка

Можно сказать, что String - это всего лишь один вид CharSequence. Однако, в отличие от CharSequence, это фактический класс, поэтому из него можно создавать объекты. Чтобы вы могли сделать это:

String myString = new String();

но вы не можете сделать это:

CharSequence myCharSequence = new CharSequence(); // error: 'CharSequence is abstract; cannot be instantiated

Поскольку CharSequence - это просто список правил, которым String соответствует, вы можете сделать это:

CharSequence myString = new String();

Это означает, что всякий раз, когда метод запрашивает CharSequence, можно присвоить ему String.

String myString = "hello";
getLength(myString); // OK

// ...

public int getLength(CharSequence text) {
    return text.length();
}

Однако обратное неверно. Если метод принимает параметр String, вы не можете передать ему что-то, что, как обычно известно, является CharSequence, потому что это может быть SpannableString или какой-то другой тип CharSequence.

CharSequence myString = "hello";
getLength(myString); // error

// ...

public int getLength(String text) {
    return text.length();
}
0 голосов
/ 29 августа 2017

CharSequence - это интерфейс, а String реализует его.Вы можете создать экземпляр String, но вы не можете сделать это для CharSequence, поскольку это интерфейс.Вы можете найти другие реализации в CharSequence на официальном веб-сайте Java.

0 голосов
/ 28 сентября 2016

CharSequence - читаемая последовательность значений char, которая реализует String. у него 4 метода

  1. charAt (int index)
  2. длина ()
  3. подпоследовательность (int start, int end)
  4. ToString ()

См. Документацию Документация CharSequence

...