1. Введение
Проще говоря, CharSequence
и String
— это две разные фундаментальные концепции в Java.
В этой быстрой статье мы рассмотрим различия между этими типами и когда использовать каждый из них.
2. Последовательность символов
CharSequence
— это интерфейс, представляющий последовательность символов. Изменчивость не обеспечивается этим интерфейсом. Поэтому и изменяемые, и неизменяемые классы реализуют этот интерфейс.
Конечно, интерфейс нельзя создать напрямую; ему нужна реализация для создания экземпляра переменной:
CharSequence charSequence = "foreach";
Здесь charSequence создается
со строкой.
Создание других реализаций:
CharSequence charSequence = new StringBuffer("foreach");
CharSequence charSequence = new StringBuilder("foreach");
3. Строка
Строка
— это последовательность символов в Java. Это неизменяемый класс и один из наиболее часто используемых типов в Java. Этот класс реализует интерфейсы CharSequence
, Serializable
и Comparable<String>
.
Ниже оба экземпляра создают строки
с одинаковым содержимым. Однако они не равны между собой:
@Test
public void givenUsingString_whenInstantiatingString_thenWrong() {
CharSequence firstString = "foreach";
String secondString = "foreach";
assertNotEquals(firstString, secondString);
}
4. CharSequence
против строки
Давайте сравним различия и общие черты CharSequence
и String
. Оба они находятся в одном пакете с именем java.lang.
, но первый — это интерфейс, а второй — конкретный класс. Более того, класс String
неизменяем.
В следующем примере каждая операция суммирования создает другой экземпляр, увеличивает объем хранимых данных и возвращает самую последнюю созданную строку:
@Test
public void givenString_whenAppended_thenUnmodified() {
String test = "a";
int firstAddressOfTest = System.identityHashCode(test);
test += "b";
int secondAddressOfTest = System.identityHashCode(test);
assertNotEquals(firstAddressOfTest, secondAddressOfTest);
}
С другой стороны, StringBuilder
обновляет уже созданную строку
, чтобы она содержала новое значение:
@Test
public void givenStringBuilder_whenAppended_thenModified() {
StringBuilder test = new StringBuilder();
test.append("a");
int firstAddressOfTest = System.identityHashCode(test);
test.append("b");
int secondAddressOfTest = System.identityHashCode(test);
assertEquals(firstAddressOfTest, secondAddressOfTest);
}
Еще одно отличие состоит в том, что интерфейс не предполагает встроенной стратегии сравнения, тогда как класс String
реализует интерфейс Comparable<String> .
Чтобы сравнить два CharSequence
, мы можем привести их к String
, а затем сравнить их:
@Test
public void givenIdenticalCharSequences_whenCastToString_thenEqual() {
CharSequence charSeq1 = "foreach_1";
CharSequence charSeq2 = "foreach_2";
assertTrue(charSeq1.toString().compareTo(charSeq2.toString()) > 0);
}
5. Вывод
Обычно мы используем String
в тех местах, где не уверены, что использовать для последовательностей символов. Однако в некоторых случаях StringBuilder
и StringBuffer
могут оказаться более подходящими.
Дополнительную информацию о CharSequence
и String можно найти в JavaDocs .
И, как всегда, реализацию всех этих примеров и фрагментов кода можно найти на Github .