Перейти к основному содержимому

Что лучше CharSequence или String в Java?

· 2 мин. чтения

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 .