Obter caractere de seqüência de caracteres por índice - Java

231

Eu sei como calcular o índice de um determinado caractere ou número em uma string, mas existe algum método predefinido que eu possa usar para me fornecer o caractere na n - ésima posição? Portanto, na string "foo", se eu pedisse o caractere com índice 0, ele retornaria "f".

Nota - na pergunta acima, por "caractere" não quero dizer o tipo de dado char, mas uma letra ou número em uma string. O importante aqui é que não recebo um caractere quando o método é chamado, mas uma string (de comprimento 1). E eu sei sobre o método substring (), mas queria saber se havia uma maneira mais clara.

Fogo azul
fonte
13
Isto é? A resposta é bem direta.
ametren
Você notou que ele não quer um charvalor? E ele sabe fazer, substring()mas só quer um jeito "mais puro". Para sua informação, posso dizer que substring()é o caminho mais limpo.
user845279
3
O @ user845279 Character.toStringatende a todos os requisitos necessários e não é nada complicado.
Ricardo Altamirano
@pythonscript Concordo, mas não é muito diferente de usar substring()diretamente.
user845279
1
Estou atrasado para esta festa, mas @RicardoAltamirano está um pouco enganado. O endIndex(segundo parâmetro) de String.substring(int, int)é um índice exclusivo e não emitirá uma exceção index + 1enquanto index < length()- o que é verdade mesmo para o último caractere na string.
William Price

Respostas:

340

O método que você está procurando é charAt. Aqui está um exemplo:

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

Para obter mais informações, consulte a documentaçãoString.charAt do Java em . Se você quiser outro tutorial simples, este ou este .

Se você não deseja o resultado como um chartipo de dados, mas como uma sequência, use o Character.toStringmétodo:

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

Se você quiser obter mais informações sobre a Characterclasse e o toStringmétodo, retirei minhas informações da documentação em Character.toString .

Ricardo Altamirano
fonte
1
"O importante aqui é que eu não recebo um caractere quando o método é chamado, mas uma string", mas, de qualquer forma, obrigado (upvote): D
Bluefire
1
Acho que a resposta de Sylvain Leroux é melhor. doc sobre Character
Chaojun Zhong 08/02
Concordo com @ChaojunZhong. Esta é uma resposta mais adequada, pois não é aconselhável usar charAt () porque você estaria tendo problemas quando tiver caracteres que precisam de 2 unidades de código.
bpunzalan
43

Você quer .charAt()

Aqui está um tutorial

"mystring".charAt(2)

retorna s

Se você está empenhado em ter uma string, existem duas maneiras de converter um caractere em uma string:

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

Ou

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

Ou até

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

Por exemplo.

ametren
fonte
@ametren É preferível a concatenação de strings Character.toString?
Ricardo Altamirano
Eu acho que isso pode se resumir a uma questão de preferência pessoal. Você também pode fazerString mychar = String.valueOf("mystring".charAt(2));
ametren 27/06/12
Para acumular, minha preferência pessoal nesse caso seria String mychar = ""+"mystring".charAt(2);porque é a mais concisa. Outros diferem em sua opinião sobre isso.
ametren
10

Nenhuma das respostas propostas funciona para pares substitutos usados ​​para codificar caracteres fora do Plano Multiligual Básico Unicode .

Aqui está um exemplo usando três técnicas diferentes para iterar sobre os "caracteres" de uma string (incluindo a API de fluxo Java 8). Observe que este exemplo inclui caracteres do plano multilíngue suplementar Unicode (SMP). Você precisa de uma fonte adequada para exibir este exemplo e o resultado corretamente.

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

Iteração de caracteres

A primeira solução é um loop simples sobre toda chara cadeia:

/* 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
}

Iteração de pontos de código

A segunda solução também usa um loop explícito, mas acessando pontos de código individuais com codePointAt e incrementando o índice de loop de acordo com 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.
}

Iterar sobre pontos de código usando a API de Stream

A terceira solução é basicamente a mesma que a segunda, mas usando a API Java 8 Stream :

/* 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
    });

Resultados

Ao executar esse programa de teste, você obtém:

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   𓊃 𓍿 𓅓 𓃡 

Como você pode ver (se você conseguir exibir hieróglifos corretamente), a primeira solução não manipula corretamente caracteres fora do Unicode BMP. Por outro lado, as outras duas soluções lidam bem com pares substitutos.

Sylvain Leroux
fonte
8

Você está bastante atolado substring(), considerando seus requisitos. A maneira padrão seria charAt(), mas você disse que não aceitará um tipo de dados char.

Thomas
fonte
Justo. Mas, como char é um tipo primitivo, suponho toString()que não funcionará e valueOf()é apenas para números (acho que posso estar errado), então como faço para converter um char em uma string?
precisa
"na pergunta acima, por" caractere "não quero dizer o tipo de dados char" - não leio como "não aceitarei um char"
ametren 27/06/12
@Bluefire Veja minha resposta. Character.toStringdeve funcionar (é um método estático da Characterclasse.
Ricardo Altamirano
5

Uma abordagem híbrida combinada charAtcom a sua exigência de não receber char pode ser

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

Mas isso não é realmente "mais limpo" do que substring()para ser honesto.

fvu
fonte
5

É tão simples quanto:

String charIs = string.charAt(index) + "";
Aqif Hamid
fonte
4

Aqui está o código correto. Se você estiver usando zybooks, isso responderá a todos os problemas.

for (int i = 0; i<passCode.length(); i++)
{
    char letter = passCode.charAt(i);
    if (letter == ' ' )
    {
        System.out.println("Space at " + i);
    }
}
silversk8terz
fonte
0

se alguém está lutando com o kotlin, o código é:

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

isso retornará o caractere na posição 1; nesse caso, lembre-se, o índice começa na posição 0; portanto, nesta amostra: kotlin seria k = posição 0, o = posição 1, t = posição 2, l = posição 3, i = posição 4 en = posição 5

Thiago Silva
fonte
-3

Como isso:

String a ="hh1hhhhhhhh";
char s = a.charAt(3);
Kadar Kabouya Kalo
fonte
O OP declarou que um Stringcomprimento 1 é desejado, não um char.
William Price
As 6 outras respostas, incluindo a aceita, sugeriram charAt()como uma solução possível. O que essa resposta adiciona?
Dan Getz
6
Além disso, parece que você está insinuando que charAt()usa índices baseados em 1, tendo o único caractere diferente ana terceira posição. Se isso fosse verdade, seria melhor você dizer ou explicar isso do que sugerir. Na realidade, isso não é verdade: charAt()usa índices baseados em 0, assim sserá 'h'.
Dan Getz