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ć?
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ć?
Odpowiedzi:
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ńczenia for (char c : str.toCharArray()) { }
wynosi ~ 250 ms, a czas ukończenia for (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ętla for
, która ocenia warunek zatrzymania każdej iteracji.)
String s = "xyz";
for(int i = 0; i < s.length(); i++)
{
char c = s.charAt(i);
}
Innym przydatnym rozwiązaniem, możesz pracować z tym ciągiem jako tablicą Ciągu
for (String s : "xyz".split("")) {
System.out.println(s);
}
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ładu for (String s : "x😁z".split("")) { System.out.println(s); }
Musisz przekonwertować obiekt String na tablicę znaków przy użyciu metody toCharArray
() klasy String:
String str = "xyz";
char arr[] = str.toCharArray(); // convert the String object to array of char
// iterate over the array using the for-each loop.
for(char c: arr){
System.out.println(c);
}
W Javie 8 możemy to rozwiązać jako:
String str = "xyz";
str.chars().forEachOrdered(i -> System.out.print((char)i));
Metoda chars () zwraca IntStream
jak wspomniano w doc :
Zwraca strumień int rozszerzających zera wartości char z tej sekwencji. Każdy znak odwzorowany na zastępczy punkt kodowy jest przekazywany przez nieinterpretowany. Jeśli sekwencja zostanie zmutowana podczas odczytywania strumienia, wynik jest niezdefiniowany.
forEachOrdered
nie iforEach
?Zachowanie forEach
jest wyraźnie niedeterministyczne, gdy jako forEachOrdered
wykonuje akcję dla każdego elementu tego strumienia, w kolejności spotkań strumienia, jeśli strumień ma zdefiniowaną kolejność spotkań. Tak forEach
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.
Niestety Java nie tworzy String
implementacji Iterable<Character>
. Można to łatwo zrobić. Jest, StringCharacterIterator
ale to nawet nie implementuje Iterator
... Więc stwórz własne:
public class CharSequenceCharacterIterable implements Iterable<Character> {
private CharSequence cs;
public CharSequenceCharacterIterable(CharSequence cs) {
this.cs = cs;
}
@Override
public Iterator<Character> iterator() {
return new Iterator<Character>() {
private int index = 0;
@Override
public boolean hasNext() {
return index < cs.length();
}
@Override
public Character next() {
return cs.charAt(index++);
}
};
}
}
Teraz możesz (nieco) łatwo uruchomić for (char c : new CharSequenceCharacterIterable("xyz"))
...
Jeśli używasz języka Java 8, możesz użyć znaku chars()
a, String
aby uzyskać jeden Stream
ze znaków, ale musisz przerzucić go z int
powrotem na a, char
ponieważ chars()
zwraca an IntStream
.
"xyz".chars().forEach(i -> System.out.print((char)i));
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 w String
.
Strings.asChars("xyz").forEach(c -> System.out.print(c));
W tym konkretnym przykładzie można również użyć odwołania do metody.
Strings.asChars("xyz").forEach(System.out::print)
Uwaga: jestem osobą odpowiedzialną za kolekcje Eclipse.
W tym przypadku możesz również użyć lambda.
String s = "xyz";
IntStream.range(0, s.length()).forEach(i -> {
char c = s.charAt(i);
});
Do Travers a String możesz także użyć charAt()
z tym łańcuchem.
lubić :
String str = "xyz"; // given String
char st = str.charAt(0); // for example we take 0 index element
System.out.println(st); // print the char at 0 index
charAt()
to metoda obsługi napisów w Javie, która pomaga przemierzać ciąg znaków dla określonego znaku.
for (char st: "xyz".toCharArray()) {}
to jest