Więc chcę iterować dla każdego znaku w ciągu.
Więc pomyślałem:
for (char c : "xyz")
ale pojawia się błąd kompilatora:
MyClass.java:20: foreach not applicable to expression type
W jaki sposób mogę to zrobić?
Najprostszym sposobem dla każdego, każdy char
w sposób String
jest użycie toCharArray()
:
for (char ch: "xyz".toCharArray()) {
}
Daje to zwięzłość konstrukcji dla każdego, ale niestety String
(która jest niezmienna) musi wykonać kopię obronną, aby wygenerować char[]
(którą można modyfikować), więc istnieje pewna kara kosztowa.
Z dokumentacji :
[
toCharArray()
zwraca] nowo przydzieloną tablicę znaków, której długość jest długością tego łańcucha i której treść jest inicjalizowana, aby zawierała sekwencję znaków reprezentowaną przez ten ciąg.
Istnieje więcej pełnych sposobów iteracji znaków w tablicy (zwykłe dla pętli CharacterIterator
itp.), Ale jeśli chcesz zapłacić toCharArray()
za to, każdy z nich jest najbardziej zwięzły.
toCharArray( )
nazywa się 3 razy?211900000
czas ukończeniafor (char c : str.toCharArray()) { }
wynosi ~ 250 ms, a czas ukończeniafor (char c : charArray) { }
wynosi <10 ms. Oczywiście te wartości czasu będą zależeć od sprzętu, ale na wynos jest to, że jedna metoda jest znacznie kosztowna niż druga.toCharArray()
nie ma go w ciele pętli; jest wywoływany tylko raz, a następnie pętla przechodzi przez wynikową tablicę. (Pętla dla każdego jest inna niż ogólna pętlafor
, która ocenia warunek zatrzymania każdej iteracji.)źródło
Innym przydatnym rozwiązaniem, możesz pracować z tym ciągiem jako tablicą Ciągu
źródło
split()
odwzorowany na więcej niż jedną postać Java, co ma miejsce w przypadku prawie wszystkich emotikonów. Na przykład ta odmiana twojego przykładufor (String s : "x😁z".split("")) { System.out.println(s); }
Musisz przekonwertować obiekt String na tablicę znaków przy użyciu metody
toCharArray
() klasy String:źródło
W Javie 8 możemy to rozwiązać jako:
Metoda chars () zwraca
IntStream
jak wspomniano w doc :Dlaczego stosowanie
forEachOrdered
nie iforEach
?Zachowanie
forEach
jest wyraźnie niedeterministyczne, gdy jakoforEachOrdered
wykonuje akcję dla każdego elementu tego strumienia, w kolejności spotkań strumienia, jeśli strumień ma zdefiniowaną kolejność spotkań. TakforEach
nie gwarantuje, że zamówienie zostanie utrzymane. Sprawdź także to pytanie aby uzyskać więcej.Możemy również użyć
codePoints()
do drukowania, zobacz tę odpowiedź, aby uzyskać więcej informacji.źródło
Niestety Java nie tworzy
String
implementacjiIterable<Character>
. Można to łatwo zrobić. Jest,StringCharacterIterator
ale to nawet nie implementujeIterator
... Więc stwórz własne:Teraz możesz (nieco) łatwo uruchomić
for (char c : new CharSequenceCharacterIterable("xyz"))
...źródło
Jeśli używasz języka Java 8, możesz użyć znaku
chars()
a,String
aby uzyskać jedenStream
ze znaków, ale musisz przerzucić go zint
powrotem na a,char
ponieważchars()
zwraca anIntStream
.Jeśli używasz Java 8 z Eclipse Collections , możesz użyć
CharAdapter
forEach
metody class z lambda lub odwołania do metody, aby iterować wszystkie znaki wString
.W tym konkretnym przykładzie można również użyć odwołania do metody.
Uwaga: jestem osobą odpowiedzialną za kolekcje Eclipse.
źródło
W tym przypadku możesz również użyć lambda.
źródło
Do Travers a String możesz także użyć
charAt()
z tym łańcuchem.lubić :
charAt()
to metoda obsługi napisów w Javie, która pomaga przemierzać ciąg znaków dla określonego znaku.źródło
for (char st: "xyz".toCharArray()) {}
to jest