Bagaimana cara menerapkan perulangan untuk setiap karakter dalam sebuah String?

189

Jadi saya ingin beralih untuk setiap karakter dalam sebuah string.

Jadi saya berpikir:

for (char c : "xyz")

tapi saya mendapatkan kesalahan kompilator:

MyClass.java:20: foreach not applicable to expression type

Bagaimana saya bisa melakukan ini?

Lyndon White
sumber

Jawaban:

333

Cara termudah untuk masing-masing chardalam Stringadalah menggunakan toCharArray():

for (char ch: "xyz".toCharArray()) {
}

Ini memberi Anda keringkasan untuk setiap konstruk, tetapi sayangnya String(yang tidak dapat diubah) harus melakukan salinan defensif untuk menghasilkan char[](yang bisa diubah), sehingga ada beberapa penalti biaya.

Dari dokumentasi :

[ toCharArray()mengembalikan] array karakter yang baru dialokasikan yang panjangnya adalah panjang dari string ini dan yang isinya diinisialisasi untuk mengandung urutan karakter yang diwakili oleh string ini.

Ada lebih banyak cara verbose untuk mengulangi karakter dalam array (reguler untuk loop CharacterIterator,, dll) tetapi jika Anda bersedia membayar biaya toCharArray()untuk-masing-masing adalah yang paling singkat.

polygenelubricants
sumber
1
Apakah kompiler akan mengenali bahwa salinan yang sebenarnya tidak diperlukan dan menerapkan optimasi yang sesuai?
Pacerier
1
@Pacerier Tidak, kompiler Java saat ini tidak akan pernah mengoptimalkan kode.
RAnders00
1
@ RAnders00 Jadi, dalam hal toCharArray( )ini disebut 3 kali?
denvercoder9
1
Dengan panjang string 211900000, waktu yang dibutuhkan untuk menyelesaikan for (char c : str.toCharArray()) { }adalah ~ 250 for (char c : charArray) { }ms dan waktu yang dibutuhkan untuk menyelesaikan adalah <10 ms. Tentu saja, nilai waktu ini akan tergantung pada perangkat keras tetapi yang perlu diperhatikan adalah bahwa satu metode jauh lebih mahal daripada yang lain.
denvercoder9
7
@ RafiduzzamanSonnet: Tidak, toCharArray()tidak ada di dalam loop body; itu hanya dipanggil sekali, dan kemudian loop berulang di atas array yang dihasilkan. (Untuk-setiap loop berbeda dari for-loop umum , yang mengevaluasi stop-kondisi setiap iterasi.)
not-just-yeti
50
String s = "xyz";
for(int i = 0; i < s.length(); i++)
{
   char c = s.charAt(i);
}

 

Matthew Flaschen
sumber
7
OP mengharapkan di-inhanced untuk loop.
AmitG
3
Turut memilih karena ini bukan yang diminta OP. Meskipun ini adalah solusi yang valid, itu sama sekali bukan apa yang diminta
Sirens
1
Tidak peduli apa yang diharapkan OP, ini memiliki kinerja yang lebih baik daripada untuk masing-masing kurasa.
Eric Wang
9

Solusi lain yang bermanfaat, Anda dapat bekerja dengan string ini sebagai array dari String

for (String s : "xyz".split("")) {
    System.out.println(s);
}
kyxap
sumber
Elegan, tetapi sayangnya itu tidak berfungsi jika ada elemen string yang split()dipetakan ke lebih dari satu karakter Java, yang merupakan kasus untuk hampir semua emotikon. Misalnya, variasi contoh Anda ini akan berulang empat kali daripada tiga:for (String s : "x😁z".split("")) { System.out.println(s); }
skomisa
5

Anda perlu mengubah objek String menjadi array char menggunakan metode toCharArray() dari kelas 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);
}
codaddict
sumber
4

Di Java 8 kita bisa menyelesaikannya sebagai:

String str = "xyz";
str.chars().forEachOrdered(i -> System.out.print((char)i));    

Method chars () mengembalikan sebuah IntStreamseperti yang disebutkan dalam doc :

Mengembalikan aliran int nol dengan memperluas nilai karakter dari urutan ini. Setiap karakter yang memetakan ke titik kode pengganti dilewatkan tanpa ditafsirkan. Jika urutan dimutasi saat aliran sedang dibaca, hasilnya tidak ditentukan.

Mengapa menggunakan forEachOrdereddan tidak forEach?

Perilaku forEachsecara eksplisit nondeterministic di mana sebagai forEachOrderedmelakukan tindakan untuk setiap elemen aliran ini, dalam urutan pertemuan aliran jika aliran memiliki urutan pertemuan yang ditentukan. Jadi forEachtidak menjamin bahwa pesanan akan disimpan. Periksa juga pertanyaan ini untuk lebih lanjut.

Kita juga bisa menggunakan codePoints()untuk mencetak, lihat jawaban ini untuk lebih jelasnya.

akhil_mittal
sumber
Ini menciptakan banyak objek, jadi jawaban ini tidak lengkap tanpa peringatan bahwa ini mungkin kurang efisien daripada loop sederhana yang diindeks.
toolforger
4

Sayangnya Java tidak membuat Stringimplementasi Iterable<Character>. Ini bisa dengan mudah dilakukan. Ada StringCharacterIteratortapi itu bahkan tidak menerapkan Iterator... Jadi buat sendiri:

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++);
            }
        };
    }
}

Sekarang Anda dapat (agak) dengan mudah menjalankan for (char c : new CharSequenceCharacterIterable("xyz"))...

Ossifer
sumber
3

Jika Anda menggunakan Java 8, Anda dapat menggunakan chars()pada Stringuntuk mendapatkan Streamkarakter, tetapi Anda harus melemparkan intkembali ke charsebagai chars()mengembalikan sebuah IntStream.

"xyz".chars().forEach(i -> System.out.print((char)i));

Jika Anda menggunakan Java 8 dengan Eclipse Collections , Anda dapat menggunakan metode CharAdapterkelas forEachdengan lambda atau metode referensi untuk beralih ke semua karakter dalam a String.

Strings.asChars("xyz").forEach(c -> System.out.print(c));

Contoh khusus ini juga bisa menggunakan referensi metode.

Strings.asChars("xyz").forEach(System.out::print)

Catatan: Saya pengendara untuk Eclipse Collections.

Donald Raab
sumber
1

Anda juga dapat menggunakan lambda dalam hal ini.

    String s = "xyz";
    IntStream.range(0, s.length()).forEach(i -> {
        char c = s.charAt(i);
    });
ander4y748
sumber
-7

Untuk Travers an String Anda juga dapat menggunakan charAt() dengan string.

Suka :

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() adalah metode penanganan string di java yang membantu untuk melintasi string untuk karakter tertentu.

pengguna1690439
sumber
2
apakah kamu tahu apa for (char st: "xyz".toCharArray()) {}itu
AmitG
Ini tidak akan dikompilasi.
Maroun
-1 off-topik (topik: untuk-masing-masing), dan penggunaan charAt bukan Charat
peenut