CharSequence против строки в Java?

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

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

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

9 ответов


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


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

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

diagram of various string-related classes and interfaces


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


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


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

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

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

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

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

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


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

CharSequence

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

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

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

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

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

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

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

строка

можно сказать, что a 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();
}

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


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

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

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