Uzyskaj ciąg znaków według indeksu - Java


230

Wiem, jak wypracować indeks określonego znaku lub liczby w ciągu, ale czy jest jakaś predefiniowana metoda, której mogę użyć, aby dać mi znak na n-tej pozycji? Więc w ciągu „foo”, gdybym poprosił o znak o indeksie 0, zwróciłby „f”.

Uwaga - w powyższym pytaniu przez „znak” nie mam na myśli typu danych char, ale literę lub cyfrę w ciągu. Ważne jest tutaj to, że nie otrzymuję znaku po wywołaniu metody, ale ciąg znaków (o długości 1). Wiem o metodzie substring (), ale zastanawiałem się, czy istnieje lepszy sposób.


13
To jest? Odpowiedź jest dość prosta.
ametren

Zauważyłeś, że on nie chce charwartości? I wie, jak to zrobić, substring()ale chce po prostu „schludniej”. FYI, mogę powiedzieć, że substring()to najładniejszy sposób.
user845279

3
@ user845279 Character.toStringspełnia wszystkie niezbędne wymagania i nie jest wcale bałagan.
Ricardo Altamirano

@pythonscript Zgadzam się, ale nie różni się niczym od substring()bezpośredniego korzystania .
user845279

1
Spóźniam się na to przyjęcie, ale @RicardoAltamirano jest trochę w błędzie. endIndex(Drugi parametr) od String.substring(int, int)jest wyłącznym indeks, a nie wyjątek na index + 1jak długo index < length()- co jest prawdą nawet do ostatniego znaku w łańcuchu.
William Price

Odpowiedzi:


339

Metoda, której szukasz charAt. Oto przykład:

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

Aby uzyskać więcej informacji, zobacz dokumentację Java na stronieString.charAt . Jeśli chcesz inny prosty samouczek, ten lub ten .

Jeśli nie chcesz, aby wynik był chartypem danych, a raczej ciągiem znaków, skorzystaj z Character.toStringmetody:

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

Jeśli chcesz uzyskać więcej informacji na temat Characterklasy i toStringmetody, wyciągnąłem moje informacje z dokumentacji Character.toString .


1
„Ważną rzeczą jest to, że nie otrzymuję znaku, gdy metoda jest wywoływana, ale ciąg znaków”, ale i tak dziękuję (głosowanie): D
Bluefire

1
Myślę, że odpowiedź Sylvaina Leroux jest lepsza. dokument o postaci
Chaojun Zhong

Zgadzam się z @ChaojunZhong to jest bardziej odpowiednie rozwiązanie, ponieważ nie jest wskazane, aby używać charAt () można byłoby przyczyną problemów, gdy masz znaki, które potrzebuje 2 jednostki kodu.
bpunzalan

43

Chcesz .charAt()

Oto samouczek

"mystring".charAt(2)

zwroty s

Jeśli masz ochotę na ciąg znaków, istnieje kilka sposobów konwersji znaku na ciąg znaków:

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

Lub

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

Lub nawet

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

Na przykład.


@ametren Czy lepiej jest łączyć łańcuchy znaków Character.toString?
Ricardo Altamirano

Myślę, że może to sprowadzać się do osobistych preferencji. Możesz także zrobićString mychar = String.valueOf("mystring".charAt(2));
ametren

Reasumując, moje osobiste preferencje w tym przypadku byłyby takie, String mychar = ""+"mystring".charAt(2);ponieważ są one najbardziej zwięzłe. Inni będą się różnić w tej opinii.
ametren

10

Żadna z proponowanych odpowiedzi nie działa w przypadku par zastępczych używanych do kodowania znaków spoza Podstawowego Multiligual Plane Unicode .

Oto przykład wykorzystujący trzy różne techniki do iteracji „znaków” ciągu (w tym przy użyciu interfejsu API strumienia Java 8). Zwróć uwagę, że ten przykład zawiera znaki z Unicode Supplementary Multilingual Plane (SMP). Potrzebujesz prawidłowej czcionki, aby poprawnie wyświetlić ten przykład i wynik.

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

Iteracja znaków

Pierwszym rozwiązaniem jest prosta pętla na całym charciągu:

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

Iteracja punktów kodowych

Drugie rozwiązanie wykorzystuje również jawną pętlę, ale uzyskuje dostęp do poszczególnych punktów kodowych za pomocą codePointAt i zwiększa indeks pętli odpowiednio do 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.
}

Iteruj po punktach kodu za pomocą Stream API

Trzecie rozwiązanie jest w zasadzie takie samo jak drugie, ale korzysta z interfejsu 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
    });

Wyniki

Po uruchomieniu tego programu testowego otrzymujesz:

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

Jak widać (jeśli potrafisz poprawnie wyświetlać hieroglify), pierwsze rozwiązanie nie obsługuje poprawnie znaków poza BMP Unicode. Z drugiej strony dwa pozostałe rozwiązania dobrze radzą sobie z parami zastępczymi.


8

Utknąłeś dość substring(), biorąc pod uwagę twoje wymagania. Standardowo byłoby charAt(), ale powiedziałeś, że nie zaakceptujesz typu danych char.


Słusznie. Ale ponieważ char jest typem prymitywnym, zakładam, toString()że na nim nie zadziała i valueOf()dotyczy tylko liczb (myślę, że się mylę), więc jak przekonwertować char na ciąg?
Bluefire

„w powyższym pytaniu przez„ znak ”nie mam na myśli typu danych char” - nie czytam tego jako „nie zaakceptuję char
ametren

@Bluefire Zobacz moją odpowiedź. Character.toStringpowinien działać (jest to metoda statyczna z Characterklasy.
Ricardo Altamirano


5

Hybrydowe podejście w połączeniu charAtz twoim wymogiem nie uzyskania char. Może być

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

Ale to nie jest tak naprawdę „schludniejsze” niż substring()szczerze mówiąc.



4

Oto poprawny kod. Jeśli używasz zybooków, rozwiąże to wszystkie problemy.

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

0

jeśli ktoś zmaga się z kotlin, kod to:

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

to zwróci char w pozycji 1, w tym przypadku k pamiętaj, indeks zaczyna się w pozycji 0, więc w tej próbce: kotlin będzie k = pozycja 0, o = pozycja 1, t = pozycja 2, l = pozycja 3, i = pozycja 4 in = pozycja 5


-3

Lubię to:

String a ="hh1hhhhhhhh";
char s = a.charAt(3);

OP stwierdził, że Stringpożądana jest długość 1, a nie a char.
William Price

6 innych odpowiedzi, w tym zaakceptowana, zaproponowano charAt()jako możliwe rozwiązanie. Co dodaje ta odpowiedź?
Dan Getz

6
Wygląda na to, że sugerujesz, że używasz charAt()wskaźników opartych na 1, ponieważ jedyną inną postacią ajest trzecia pozycja. Gdyby to była prawda, lepiej byłoby powiedzieć to lub wyjaśnić, niż wskazać na to. W rzeczywistości, która jest nie prawdą charAt()używa 0 bazie indeksów, tak sbędzie 'h'.
Dan Getz
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.