Làm cách nào để áp dụng vòng lặp for cho mỗi ký tự trong Chuỗi?


189

Vì vậy, tôi muốn lặp lại cho mỗi ký tự trong một chuỗi.

Vì vậy, tôi nghĩ:

for (char c : "xyz")

nhưng tôi gặp lỗi trình biên dịch:

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

Tôi có thể làm cái này như thế nào?

Câu trả lời:


333

Cách dễ nhất để sử dụng cho mỗi thứ chartrong một Stringlà sử dụng toCharArray():

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

Điều này mang lại cho bạn sự đồng nhất của từng cấu trúc, nhưng thật không may String(không thể thay đổi) phải thực hiện một bản sao phòng thủ để tạo ra char[](có thể thay đổi), do đó có một số hình phạt chi phí.

Từ tài liệu :

[ toCharArray()trả về] một mảng ký tự mới được phân bổ có độ dài là độ dài của chuỗi này và có nội dung được khởi tạo để chứa chuỗi ký tự được đại diện bởi chuỗi này.

Có nhiều cách lặp lại dài dòng hơn các ký tự trong một mảng (thường xuyên cho vòng lặp CharacterIterator, v.v.) nhưng nếu bạn sẵn sàng trả chi phí toCharArray()cho - thì mỗi cách là ngắn gọn nhất.


1
Trình biên dịch sẽ nhận ra rằng một bản sao thực sự là không cần thiết và áp dụng các tối ưu hóa phù hợp?
Pacerier

1
@Pacerier Không, trình biên dịch Java hiện tại sẽ không bao giờ tối ưu hóa mã.
RAnders00

1
@ RAnders00 Vậy, trong trường hợp toCharArray( )này được gọi là 3 lần?
denvercoder9

1
Với độ dài chuỗi 211900000, thời gian thực hiện để hoàn thành for (char c : str.toCharArray()) { }là ~ 250ms và thời gian thực hiện để hoàn thành for (char c : charArray) { }là <10ms. Tất nhiên, các giá trị thời gian này sẽ phụ thuộc vào phần cứng, nhưng điều đáng nói là một phương pháp này có chi phí đáng kể so với phương pháp khác.
denvercoder9

7
@RafiduzzamanSonnet: Không, toCharArray()không nằm trong thân vòng lặp; nó chỉ được gọi một lần và sau đó vòng lặp lặp qua mảng kết quả đó. (Vòng lặp for- forevery khác với vòng lặp chung , đánh giá điều kiện dừng mỗi lần lặp.)
không chỉ là

50
String s = "xyz";
for(int i = 0; i < s.length(); i++)
{
   char c = s.charAt(i);
}

 


7
OP đang mong đợi được hít vào vòng lặp.
AmitG

3
Bỏ phiếu vì đây không phải là điều OP yêu cầu. Mặc dù đây là một giải pháp hợp lệ nhưng nó hoàn toàn không phải là những gì đang được hỏi
Sirens

1
Không có vấn đề gì với OP, điều này có hiệu suất tốt hơn so với tôi đoán.
Eric Wang

9

Một giải pháp hữu ích khác, bạn có thể làm việc với chuỗi này dưới dạng mảng Chuỗi

for (String s : "xyz".split("")) {
    System.out.println(s);
}

Thanh lịch, nhưng thật không may, nó không hoạt động nếu bất kỳ phần tử nào của chuỗi được split()ánh xạ tới nhiều hơn một ký tự Java, đó là trường hợp của hầu hết tất cả các biểu tượng cảm xúc. Ví dụ: biến thể ví dụ này của bạn sẽ lặp bốn lần thay vì ba lần:for (String s : "x😁z".split("")) { System.out.println(s); }
skomisa

5

Bạn cần chuyển đổi đối tượng String thành một mảng char bằng toCharArrayphương thức () của lớp 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);
}

4

Trong Java 8, chúng ta có thể giải nó như sau:

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

Phương thức chars () trả về một IntStreamnhư đã đề cập trong doc :

Trả về một luồng int zero - mở rộng các giá trị char từ chuỗi này. Bất kỳ char nào ánh xạ tới một điểm mã thay thế đều được chuyển qua không giải thích được. Nếu chuỗi bị đột biến trong khi luồng đang được đọc, kết quả không được xác định.

Tại sao sử dụng forEachOrderedvà không forEach?

Hành vi của forEachkhông rõ ràng là không forEachOrderedthực hiện khi hành động thực hiện một hành động cho từng thành phần của luồng này, theo thứ tự bắt gặp của luồng nếu luồng có thứ tự bắt gặp được xác định. Vì vậy, forEachkhông đảm bảo rằng thứ tự sẽ được giữ. Ngoài ra kiểm tra câu hỏi này để biết thêm.

Chúng tôi cũng có thể sử dụng codePoints()để in, xem câu trả lời này để biết thêm chi tiết.


Điều này tạo ra nhiều đối tượng, vì vậy câu trả lời này không đầy đủ nếu không có sự cảnh báo rằng điều này có thể kém hiệu quả hơn một vòng lặp được lập chỉ mục đơn giản.
toolforger

4

Thật không may, Java không thực Stringhiện Iterable<Character>. Điều này có thể dễ dàng được thực hiện. Có StringCharacterIteratornhưng điều đó thậm chí không thực hiện Iterator... Vì vậy, hãy tạo của riêng bạn:

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

Bây giờ bạn có thể (phần nào) dễ dàng chạy for (char c : new CharSequenceCharacterIterable("xyz"))...


3

Nếu bạn sử dụng Java 8, bạn có thể sử dụng chars()trên Stringđể có được một Streamnhân vật, nhưng bạn sẽ cần phải cast inttrở lại một charkhi chars()trở lại một IntStream.

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

Nếu bạn sử dụng Java 8 với Bộ sưu tập Eclipse , bạn có thể sử dụng phương thức CharAdapterlớp forEachvới lambda hoặc tham chiếu phương thức để lặp lại tất cả các ký tự trong a String.

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

Ví dụ cụ thể này cũng có thể sử dụng một tham chiếu phương thức.

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

Lưu ý: Tôi là người đi làm cho Bộ sưu tập Eclipse.


1

Bạn cũng có thể sử dụng lambda trong trường hợp này.

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

-7

Đối với Travers, bạn cũng có thể sử dụng Chuỗi charAt() với chuỗi.

giống :

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() là phương thức xử lý chuỗi trong java giúp Travers chuỗi cho ký tự cụ thể.


2
bạn có biết nó for (char st: "xyz".toCharArray()) {}là gì không?
AmitG

Điều này sẽ không biên dịch.
Maroun

-1 ngoài chủ đề (chủ đề: cho mỗi người) và sử dụng charAt thay vì charAT
peenut
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.