for-each 루프를 문자열의 모든 문자에 어떻게 적용합니까?


189

그래서 문자열의 각 문자를 반복하고 싶습니다.

그래서 나는 생각했다.

for (char c : "xyz")

하지만 컴파일러 오류가 발생합니다.

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

어떻게해야합니까?

답변:


333

대한-각 각에 가장 쉬운 방법 charA의가 String사용하는 것입니다 toCharArray():

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

이것은 for-each 구성의 간결성을 제공하지만 불행히도 String(불변)는 char[](변경 가능) 을 생성하기 위해 방어 사본을 수행해야 하므로 비용이 약간 듭니다.

로부터 문서 :

[ toCharArray()복귀] 새로 할당 된 문자 배열 이 문자열의 길이와 내용이 문자열로 표시하는 문자 시퀀스를 포함하도록 초기화된다.

배열에서 문자를 반복하는 더 자세한 방법이 CharacterIterator있지만 (정규 for 루프 등), toCharArray()각 비용 을 기꺼이 지불하려는 경우 가장 간결합니다.


1
컴파일러는 실제 사본이 필요하지 않다는 것을 인식하고 적절한 최적화를 적용합니까?
Pacerier

1
@Pacerier 아니요, 현재 Java 컴파일러는 코드를 최적화하지 않습니다.
RAnders00

1
@ RAnders00 그렇다면이 경우 toCharArray( )3 번이라고합니까?
denvercoder9

1
문자열 길이가 211900000이면 완료하는 데 걸리는 시간 for (char c : str.toCharArray()) { }은 ~ 250ms이고 완료하는 데 걸리는 시간 for (char c : charArray) { }은 <10ms입니다. 물론 이러한 시간 값은 하드웨어에 따라 달라 지지만 한 가지 방법은 다른 방법보다 비용이 많이 듭니다.
denvercoder9

7
@RafiduzzamanSonnet : 아니오, toCharArray()루프 몸체 내부가 아닙니다. 한 번만 호출 된 다음 루프는 결과 배열을 반복합니다. (for-each 루프는 for각 반복 중지 조건을 평가 하는 일반 -loop와 다릅니다 .)
not-

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

 


7
OP는 향상된 for 루프를 기대하고 있습니다.
AmitG

3
이것은 OP가 요청한 것이 아니기 때문에 투표에 실패했습니다. 이것은 유효한 해결책이지만 그것은 요구되는 것이 아닙니다
Sirens

1
OP가 무엇을 기대하든, 이것은 내가 생각하는 것보다 성능이 더 좋습니다.
Eric Wang

9

또 다른 유용한 솔루션은이 문자열을 문자열 배열로 사용할 수 있습니다.

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

우아하지만 불행히도 문자열의 요소 split()가 둘 이상의 Java 문자 에 매핑 되는 경우 작동하지 않습니다 . 이는 거의 모든 이모티콘의 경우입니다. 예를 들어,이 예제의 변형은 세 개가 아닌 네 번 반복됩니다.for (String s : "x😁z".split("")) { System.out.println(s); }
skomisa

5

toCharArrayString 클래스 의 () 메서드를 사용하여 String 객체를 char 배열로 변환해야합니다 .

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

Java 8 에서는 다음과 같이 해결할 수 있습니다.

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

chars () 메소드 IntStreamdoc 에서 언급 한대로를 반환합니다 .

이 순서로부터 char 값을 제로 확장하는 int의 스트림을 돌려줍니다. 대리 코드 포인트에 매핑되는 모든 문자는 해석되지 않은 상태로 전달됩니다. 스트림을 읽는 동안 시퀀스가 ​​변경되면 결과가 정의되지 않습니다.

왜 사용 forEachOrdered하지 forEach않습니까?

의 동작이 forEach명확하게 결정적되는 위치로서 forEachOrdered수행이 스트림의 각 요소에 대한 액션, 스트림의 발생 순서 스트림 정의 발생 순서를 갖는 경우. 따라서 forEach주문이 유지된다는 보장은 없습니다. 또한이 질문 을 확인하십시오 .

codePoints()인쇄 에도 사용할 수 있습니다 . 자세한 내용 은이 답변 을 참조하십시오.


이렇게하면 여러 객체가 생성되므로 간단한 색인 루프보다 효율성이 떨어질 수 있다는 경고가 없으면이 답변이 완료되지 않습니다.
toolforger

4

불행히도 Java는 String구현 하지 않습니다 Iterable<Character>. 이것은 쉽게 할 수 있습니다. 이 StringCharacterIterator하지만도 구현하지 않습니다 Iterator... 그래서 자신합니다

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

이제 (어쩌면) 쉽게 실행할 수 있습니다 for (char c : new CharSequenceCharacterIterable("xyz"))...


3

Java 8을 사용하는 경우 chars()a String를 사용 하여 Stream문자 를 얻을 수 있지만 as int를 a charchars()반환해야합니다 IntStream.

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

Eclipse Collections 와 함께 Java 8을 사용하는 경우 CharAdapter클래스 forEach메소드를 람다 또는 메소드 참조와 함께 사용하여의 모든 문자를 반복 할 수 있습니다 String.

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

이 특정 예제는 메소드 참조를 사용할 수도 있습니다.

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

참고 : 저는 Eclipse Collections의 커미터입니다.


1

이 경우 람다를 사용할 수도 있습니다.

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

-7

문자열 트래버스의 경우 문자열 charAt()과 함께 사용할 수도 있습니다 .

처럼 :

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() 특정 문자에 대한 문자열을 순회하는 데 도움이되는 Java의 문자열 처리 방법입니다.


2
뭔지 알아 for (char st: "xyz".toCharArray()) {}?
AmitG

컴파일되지 않습니다.
Maroun

주 제외 -1 개 (주제 : 각 주제), charAT 대신 charAt
peenut
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.