Javaストリームによる文字列操作

Javaストリームを使用した文字列操作

1. 概要

Java 8では、宣言的な方法でデータを処理できる新しいStreamAPIが導入されました。

この簡単な記事では、Stream APIを使用してコンマ区切りのStringStringsのリストに分割する方法と、String配列をに結合する方法を学習します。カンマで区切られたString

また、StreamAPIを使用して文字列配列をマップに変換する方法についても説明します。

ほぼ常に、いくつかのJava Collectionsを繰り返し、いくつかのフィルタリングロジックに基づいてCollectionをフィルタリングする必要がある状況に直面します。 このタイプの状況に対する従来のアプローチでは、多くのループとif-else操作を使用して、目的の結果を取得していました。

Stream APIについて詳しく知りたい場合は、this articleを確認してください。

2. StreamAPIを使用した文字列の結合

Stream APIを使用して、String配列をコンマ区切りのStringに結合する関数を作成しましょう。

public static String join(String[] arrayOfString){
    return Arrays.asList(arrayOfString)
      .stream()
      //.map(...)
      .collect(Collectors.joining(","));
}

ここで注意すべき点:

  • stream()関数は、任意のCollectionをデータのストリームに変換します

  • map()関数はデータの処理に使用されます

  • filter()という名前の別の関数もあり、フィルタリング基準を含めることができます

Stringを固定のプレフィックスとポストフィックスで結合したいシナリオがあります。 Stream APIを使用すると、次の方法でそれを行うことができます。

public static String joinWithPrefixPostfix(String[] arrayOfString){
    return Arrays.asList(arrayOfString)
      .stream()
      //.map(...)
      .collect(Collectors.joining(",","[","]"));
}

Collectors.joining()メソッドでわかるように、プレフィックスを‘[‘として宣言し、ポストフィックスを‘]'として宣言しています。したがって、生成されたStringは、宣言された[…..]形式で作成されます。

3. Stream APIを使用したStringsの分割

次に、Stream APIを使用して、コンマで区切られたStringStringのリストに分割する関数を作成しましょう。

public static List split(String str){
    return Stream.of(str.split(","))
      .map (elem -> new String(elem))
      .collect(Collectors.toList());
}

Stream APIを使用して、StringCharacterリストに直接変換することもできます。

public static List splitToListOfChar(String str) {
    return str.chars()
      .mapToObj(item -> (char) item)
      .collect(Collectors.toList());
}

ここで注意すべき興味深い事実の1つは、chars()メソッドがStringIntegerのストリームに変換することです。ここで、各Integer値はそれぞれのASCII値を示します。すべてのCharシーケンス。 そのため、mapToObj()メソッドでマッパーオブジェクトを明示的にタイプキャストする必要があります。

4. String arrayからMap へのStream API

配列内の各項目に区切り文字で連結されたKey-Valueエンティティが含まれている場合は、split Collectors.toMapを使用してString配列をマップに変換することもできます。

public static Map arrayToMap(String[] arrayOfString) {
    return Arrays.asList(arrayOfString)
      .stream()
      .map(str -> str.split(":"))
      .collect(toMap(str -> str[0], str -> str[1]));
}

ここで、“:”は、文字列配列内のすべての要素のキーと値の区切り文字です。

Please remember that in order to avoid compilation error, we need to ensure that code is compiled using Java 1.8。 これを行うには、pom.xmlに次のプラグインを追加する必要があります。


    
      
        org.apache.maven.plugins
        maven-compiler-plugin
        3.3
        
          1.8
          1.8
        
      
    

5. テスト

関数の作成が完了したので、結果を検証するためのテストケースを作成しましょう。

まず、簡単な結合方法をテストしましょう。

@Test
public void givenArray_transformedToStream_convertToString() {
    String[] programmingLanguages = {"java", "python", "nodejs", "ruby"};
    String expectation = "java,python,nodejs,ruby";

    String result  = JoinerSplitter.join(programmingLanguages);
    assertEquals(result, expectation);
}

次に、別の分割機能を作成して、単純な分割機能をテストしましょう。

@Test
public void givenString_transformedToStream_convertToList() {
    String programmingLanguages = "java,python,nodejs,ruby";

    List expectation = new ArrayList<>();
    expectation.add("java");
    expectation.add("python");
    expectation.add("nodejs");
    expectation.add("ruby");

    List result  = JoinerSplitter.split(programmingLanguages);

    assertEquals(result, expectation);
}

最後に、String配列をテストして機能をマップしましょう。

@Test
public void givenStringArray_transformedToStream_convertToMap() {

    String[] programming_languages = new String[] {"language:java","os:linux","editor:emacs"};

    Map expectation=new HashMap<>();
    expectation.put("language", "java");
    expectation.put("os", "linux");
    expectation.put("editor", "emacs");

    Map result = JoinerSplitter.arrayToMap(programming_languages);
    assertEquals(result, expectation);

}

同様に、残りのテストケースを作成する必要があります。

6. 結論

Stream APIは、高度なデータ処理技術を提供します。 この新しいコード記述方法は、マルチスレッド環境でのヒープメモリ管理の点で非常に効率的です。

いつものように、完全なソースコードはover on Githubで利用できます。