Получить строковый символ по индексу - Java

231

Я знаю, как определить индекс определенного символа или числа в строке, но есть ли какой-нибудь предопределенный метод, который я могу использовать, чтобы дать мне символ в n-й позиции? Таким образом, в строке «foo», если бы я запросил символ с индексом 0, он вернул бы «f».

Примечание. В приведенном выше вопросе под «символом» я подразумеваю не тип данных char, а букву или цифру в строке. Здесь важно то, что при вызове метода я получаю не символ, а строку (длиной 1). И я знаю о методе substring (), но мне было интересно, есть ли более аккуратный способ.

Синий огонь
источник
13
Это? Ответ довольно прост.
Ametren
Вы заметили, что он не хочет charценность? И он знает, как это сделать, substring()но просто хочет "аккуратнее". К вашему сведению, я могу сказать, что substring()это самый лучший способ.
user845279
3
@ user845279 Character.toStringвыполняет все необходимые требования и совсем не беспорядочно.
Рикардо Альтамирано
@ Pythonscript Я согласен, но это не сильно отличается от использования substring()напрямую.
user845279
1
Я опаздываю на эту вечеринку, но @RicardoAltamirano немного ошибается. endIndex(Второй параметр) из String.substring(int, int)является эксклюзивным индексом, и он не будет бросать исключение для index + 1тех пор , пока index < length()- что верно даже для последнего символа в строке.
Уильям Прайс

Ответы:

340

Метод, который вы ищете, это charAt. Вот пример:

String text = "foo";
char charAtZero = text.charAt(0);
System.out.println(charAtZero); // Prints f

Для получения дополнительной информации см. Документацию по JavaString.charAt . Если вы хотите другой простой учебник, этот или этот .

Если вам не нужен результат как charтип данных, а как строка, вы должны использовать Character.toStringметод:

String text = "foo";
String letter = Character.toString(text.charAt(0));
System.out.println(letter); // Prints f

Если вам нужна дополнительная информация о Characterклассе и toStringметоде, я извлек свою информацию из документации на Character.toString .

Рикардо Альтамирано
источник
1
«Важно то, что я не получаю символ, когда метод вызывается, но строку», но все равно спасибо (upvote): D
Bluefire
1
Я думаю, что ответ Сильвен Леру лучше. документ о персонаже
Чаоцзюнь Чжун
Я согласен с @ChaojunZhong, это более подходящий ответ, так как не рекомендуется использовать charAt (), потому что у вас будут проблемы, когда у вас есть символы, которым нужно 2 единицы кода.
bpunzalan
43

Вы хотите .charAt()

Вот учебник

"mystring".charAt(2)

возвращается s

Если вы склонны к наличию строки, есть несколько способов преобразовать символ в строку:

String mychar = Character.toString("mystring".charAt(2));

Или

String mychar = ""+"mystring".charAt(2);

Или даже

String mychar = String.valueOf("mystring".charAt(2));

Например.

ametren
источник
@ametren Предпочтительна ли конкатенация строк Character.toString?
Рикардо Альтамирано
Я думаю, что это может сводиться к вопросу личных предпочтений. Вы также можете сделатьString mychar = String.valueOf("mystring".charAt(2));
Ametren
В общем, моё личное предпочтение в этом случае было бы String mychar = ""+"mystring".charAt(2);потому, что оно наиболее лаконично. Другие будут расходиться во мнениях по этому поводу.
Аметрен
10

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

Вот пример, использующий три различных метода для перебора «символов» строки (включая использование потокового API Java 8). Обратите внимание, что этот пример включает символы дополнительной многоязычной плоскости (SMP) Unicode. Вам нужен правильный шрифт, чтобы правильно отобразить этот пример и результат.

// String containing characters of the Unicode 
// Supplementary Multilingual Plane (SMP)
// In that particular case, hieroglyphs.
String str = "The quick brown 𓃥 jumps over the lazy 𓊃𓍿𓅓𓃡";

Итерация символов

Первое решение - простой цикл по всей charстроке:

/* 1 */
System.out.println(
        "\n\nUsing char iterator (do not work for surrogate pairs !)");
for (int pos = 0; pos < str.length(); ++pos) {
    char c = str.charAt(pos);
    System.out.printf("%s ", Character.toString(c));
    //                       ^^^^^^^^^^^^^^^^^^^^^
    //                   Convert to String as per OP request
}

Итерация кодовых точек

Второе решение также использует явный цикл, но получает доступ к отдельным кодам с помощью codePointAt и увеличивает индекс цикла в соответствии с charCount :

/* 2 */
System.out.println(
        "\n\nUsing Java 1.5 codePointAt(works as expected)");
for (int pos = 0; pos < str.length();) {
    int cp = str.codePointAt(pos);

    char    chars[] = Character.toChars(cp);
    //                ^^^^^^^^^^^^^^^^^^^^^
    //               Convert to a `char[]`
    //               as code points outside the Unicode BMP
    //               will map to more than one Java `char`
    System.out.printf("%s ", new String(chars));
    //                       ^^^^^^^^^^^^^^^^^
    //               Convert to String as per OP request

    pos += Character.charCount(cp);
    //     ^^^^^^^^^^^^^^^^^^^^^^^
    //    Increment pos by 1 of more depending
    //    the number of Java `char` required to
    //    encode that particular codepoint.
}

Перебирать кодовые точки с помощью Stream API

Третье решение в основном такое же, как и второе, но с использованием Java 8 Stream API :

/* 3 */
System.out.println(
        "\n\nUsing Java 8 stream (works as expected)");
str.codePoints().forEach(
    cp -> {
        char    chars[] = Character.toChars(cp);
        //                ^^^^^^^^^^^^^^^^^^^^^
        //               Convert to a `char[]`
        //               as code points outside the Unicode BMP
        //               will map to more than one Java `char`
        System.out.printf("%s ", new String(chars));
        //                       ^^^^^^^^^^^^^^^^^
        //               Convert to String as per OP request
    });

Полученные результаты

Когда вы запускаете эту тестовую программу, вы получаете:

Using char iterator (do not work for surrogate pairs !)
T h e   q u i c k   b r o w n   ? ?   j u m p s   o v e r   t h e   l a z y   ? ? ? ? ? ? ? ? 

Using Java 1.5 codePointAt(works as expected)
T h e   q u i c k   b r o w n   𓃥   j u m p s   o v e r   t h e   l a z y   𓊃 𓍿 𓅓 𓃡 

Using Java 8 stream (works as expected)
T h e   q u i c k   b r o w n   𓃥   j u m p s   o v e r   t h e   l a z y   𓊃 𓍿 𓅓 𓃡 

Как вы можете видеть (если вы умеете правильно отображать иероглифы), первое решение не обрабатывает символы должным образом за пределами BMP Unicode. С другой стороны, два других решения хорошо работают с суррогатными парами.

Сильвен Леру
источник
8

Вы довольно застряли substring(), учитывая ваши требования. Стандартный способ был бы charAt(), но вы сказали, что не примете тип данных char.

Томас
источник
Справедливо. Но, поскольку char - это примитивный тип, я предполагаю, что toString()он не будет работать с ним, и valueOf()только для чисел (думаю, я могу ошибаться), так как мне преобразовать char в строку?
Bluefire
«в приведенном выше вопросе под« символом »я не подразумеваю тип данных char» - я не читаю это как «я не приму char»
ametren
@Bluefire Смотрите мой ответ. Character.toStringдолжен работать (это статический метод из Characterкласса.
Рикардо Альтамирано
5

Гибридный подход в сочетании charAtс вашим требованием не получить чар может быть

newstring = String.valueOf("foo".charAt(0));

Но это не совсем "аккуратно", substring()если честно.

ФВУ
источник
5

Это так просто, как:

String charIs = string.charAt(index) + "";
Акиф Хамид
источник
4

Вот правильный код. Если вы используете zybooks, это решит все проблемы.

for (int i = 0; i<passCode.length(); i++)
{
    char letter = passCode.charAt(i);
    if (letter == ' ' )
    {
        System.out.println("Space at " + i);
    }
}
silversk8terz
источник
0

если кто-то борется с kotlin, код:

var oldStr: String = "kotlin"
var firstChar: String = oldStr.elementAt(0).toString()
Log.d("firstChar", firstChar.toString())

это вернет символ в позиции 1, в этом случае k запомните, индекс начинается в позиции 0, поэтому в этом примере: kotlin будет k = позиция 0, o = позиция 1, t = позиция 2, l = позиция 3, я = положение 4 и n = положение 5

Тиаго Сильва
источник
-3

Как это:

String a ="hh1hhhhhhhh";
char s = a.charAt(3);
Кадар Кабуя Кало
источник
ОП заявил, что Stringжелательна длина 1, а не а char.
Уильям Прайс
6 других ответов, включая принятый, предложены charAt()в качестве возможного решения. Что добавляет этот ответ?
Дэн Гетц
6
Кроме того, похоже, что вы намекаете, что charAt()используют индексы, основанные на 1, имея только другой символ в aтретьей позиции. Если бы это было правдой, то для вас было бы лучше сказать или объяснить это, чем намекать на это. В действительности это не так: charAt()использует индексы, основанные на 0, так sи будет 'h'.
Дэн Гетц