文字列のすべての文字にfor-eachループを適用するにはどうすればよいですか?


189

そのため、文字列内の各文字を反復処理します。

ので、私は考えました:

for (char c : "xyz")

しかし、私はコンパイラエラーを受け取ります:

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

これどうやってするの?

回答:


333

以下のため、各ごとに最も簡単な方法charではString使用することですtoCharArray()

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

これにより、for-eachコンストラクトが簡潔になりますが、残念ながらString(これは不変です)、防御コピーを実行して、char[](変更可能です)多少のコストがかかります。

ドキュメントから:

[ toCharArray()戻り値] この文字列の長さであり、その内容がこの文字列で表される文字シーケンスを含むように初期化される、新しく割り当てられた文字配列

配列の文字を反復するより詳細な方法(通常のforループCharacterIteratorなど)がありますが、コストを支払うことをいとわない場合toCharArray()は、最も簡潔です。


1
コンパイラーは真のコピーが不要であることを認識し、適切な最適化を適用しますか?
Pacerier 2014

1
@Pacerierいいえ、現在のJavaコンパイラはコードを最適化しません。
RAnders00 2016

1
@ RAnders00では、この場合、toCharArray( )3回呼び出されますか?
denvercoder9

1
文字列の長さがの211900000場合、完了までにかかる時間for (char c : str.toCharArray()) { }は約250ミリ秒で、完了するまでの時間for (char c : charArray) { }は<10ミリ秒です。もちろん、これらの時間値はハードウェアに依存しますが、1つの方法は他の方法よりもかなりコストがかかるということを覚えておいてください。
denvercoder9

7
@RafiduzzamanSonnet:いいえ、toCharArray()ループ本体の内部にはありません。それは1回だけ呼び出され、ループは結果の配列を反復処理します。(for-eachループはfor、反復ごとに停止条件を評価する一般的な-loop とは異なります。)
not-just-yeti

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

 


7
OPは強化されたforループを期待しています。
AmitG 2013

3
これは特にOPが要求したものではないため、反対票が投じられました。これは有効な解決策ですが、求められていることはまったく
異なります

1
OPが何を期待していても、これは私が推測するそれぞれのパフォーマンスよりも優れたパフォーマンスを発揮します。
Eric Wang

9

別の便利な解決策は、この文字列を文字列の配列として扱うことです。

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

エレガントですが、残念ながら、文字列のいずれかの要素がsplit()複数のJava 文字にマップされている場合は機能しません。これは、ほとんどすべての絵文字に当てはまります。たとえば、あなたの例の意志ループのこの変化は4回ではなく3: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 2018年

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を使用してa Streamの文字を取得できますがintcharchars()返すので、a にキャストし直す必要がありますIntStream

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

EclipseコレクションでJava 8を使用する場合は、CharAdapterクラスforEachメソッドをラムダまたはメソッド参照とともに使用して、のすべての文字を反復処理できますString

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

この特定の例では、メソッド参照も使用できます。

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

注:私はEclipseコレクションのコミッターです。


1

この場合はラムダを使用することもできます。

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

-7

Travers a Stringを使用することもできます 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 2013

これはコンパイルされません。
Maroun 2013

-1オフトピック(トピック:for-each)、charATの代わりにcharAtを使用
peenut
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.