2015-09-09 12 views
8

時には、文字列内の各文字で簡単なことをしたいことがあります。残念なことに、文字列は不変であるため、文字列をループする以外はそれほど冗長ではありません。代わりにストリームを使用する場合は、1〜2行でずっと短くできます。文字列をjava.util.Streamに変換する<Character>

StringStream<Character>に変換する方法はありますか?

答えて

7

あなたはCharSequenceで提供chars()方法を使用することができますし、Stringクラスは、このインタフェースを実装しているので、あなたはそれにアクセスすることができます。 chars()方法はIntStreamを返すので、あなたは、例えばIntStream

Stream<Character>に変換するようになる場合 (char)にキャストする必要があります

public class Foo { 

    public static void main(String[] args) { 
     String x = "new"; 

     Stream<Character> characters = x.chars().mapToObj(i -> (char) i); 
     characters.forEach(System.out::println); 
    } 
} 
+0

文字列にJava文字に収まらないUnicode文字が含まれている場合、この解決策は機能しません。これは、たとえば、いくつかの難解な言語や顔文字でのケースです。それを処理するソリューションについては、[Tagirの答え](https://stackoverflow.com/a/32472793/452775)を参照してください。 – Lii

1

charsメソッドはIntStreamを返し、それをcharにマッピングすると、Stream<Character>になります。我々はそれがCharacter内部intcharへとJavaの自動箱入りがマッピングされているので、mapToObj戻りObjectは、我々の場合CharacterStreamStreamを高く評価しました。

Stream<Character> stream = "abc".chars().mapToObj(c -> (char)c); 

また、グアバ(com.google.common.collect.Lists)の助けを借りて、あなたはStringからCharacterの不変のリストを返したこの、のようにそれを使用することができます。

Stream<Character> stream = Lists.charactersOf("abc").stream(); 
5

それはIntStreamあるコードポイントのストリームを使用するために通常より安全です:

IntStream codePoints = string.codePoints(); 

この方法では、任意のUnicodeのシンボルと正しい結果がありますので、Unicodeのサロゲートペアは、単一のコードポイントにマージされます。使用例:

String result = string.codePoints().map(Character::toUpperCase) 
     .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) 
     .toString(); 

はまた、このように、それはStream<Character>を処理するよりもさらに効果的であるかもしれない、あなたはボクシングを避けることに注意してください。こうした流れを収集する

もう一つの方法は、個別のStringBuilderを使用することです:

StringBuilder sb = new StringBuilder(); 
String result = string.codePoints().map(Character::toUpperCase) 
         .forEachOrdered(sb::appendCodePoint); 

、このようなアプローチは、以下の機能見えますが、あなたがすでにStringBuilderを持っているか、後にもっと何かを連結したい場合は、それがより効率的かもしれ同じ文字列。

+1

chars()に優先してcodePoints()を提案するのに加えて、もう一つ。 –

関連する問題