CharSequence VS String в Java?

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

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

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

Ответ 1

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

Ответ 2

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

Ответ 3

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

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

diagram of various string-related classes and interfaces

Ответ 4

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

Ответ 5

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

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

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

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

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

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

Ответ 6

Проблема, которая возникает в практическом коде 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()); 

Ответ 7

CharSequence

A CharSequence - это интерфейс, а не действительный класс. Интерфейс - это всего лишь набор правил (методов), которые должен содержать класс, если он реализует интерфейс. В Android a 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();
}

Ответ 8

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

Ответ 9

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

  • charAt (int index)
  • длина()
  • subSequence (int start, int end)
  • ToString()

Пожалуйста, обратитесь к документации Документация CharSequence