プログラマーズJavaチートシート4. JavaストリームAPI





かなり前にJava 8がリリースされたという事実にもかかわらず、すべてのプログラマーがその新機能を使用するわけではありません。誰かがAndroidプロジェクトを行っており、ラムダとStream Apiの実装にサードパーティのライブラリを使用したくない、または使用できない。 ただし、インタビューではJavaプログラマーのラムダとStream Apiの知識が必要になることがよくあり、Java 8が使用されているプロジェクトに切り替えるときに役立つだけです。 ラムダと関数型プログラミングの知識は必要ありません(すべてを明確にするために例を示しました)。これは、Javaの最も基本的な知識以上のレベルです。



また、これはチートシートであるため、この記事を使用して、Java Stream Apiの特定の機能がどのように機能するかをすばやく覚えることができます。 主な機能の機能の簡単なリストは、記事の冒頭に記載されています。





Stream Apiが何なのかわからない人のために
ストリームAPIは、機能的なスタイルでデータ構造を操作するための新しい方法です。 ほとんどの場合、Java 8のストリームを使用してコレクションを操作しますが、実際にはこのメカニズムはさまざまなデータに使用できます。



Stream Apiを使用すると、コレクションからすべての奇数の合計を取得するタスクが次のコードによって解決される前に、SQLのスタイルでデータ構造の処理を記述できます。

Integer sumOddOld = 0; for(Integer i: collection) { if(i % 2 != 0) { sumOddOld += i; } }
      
      





次に、Stream Apiを使用して、機能的なスタイルでこの問題を解決できます。

  Integer sumOdd = collection.stream().filter(o -> o % 2 != 0).reduce((s1, s2) -> s1 + s2).orElse(0);
      
      





さらに、Stream Apiを使用すると、追加のコードなしでstream()をparallelStream()に変更するだけで問題を並列に解決できます

  Integer sumOdd = collection.parallelStream().filter(o -> o % 2 != 0).reduce((s1, s2) -> s1 + s2).orElse(0);
      
      





セマフォ、同期、デッドロックのリスクなどなく、すでにコードを並列化します。





一般的な目次「チートシート」
1. JPAとHibernateの質問と回答

2. GitHubで最も人気のある350以上の非モバイルJavaオープンソースプロジェクト

3. Javaのコレクション(標準、グアバ、Apache、Trove、GSコレクションなど

4. Java Stream API

5.講義およびJavaの講義の250のロシア語教育ビデオ

6. Javaプログラマー向けの便利なリンクのリスト

7典型的なタスク

7.1 InputStreamを文字列に変換する最適な方法

7.2部分文字列の出現回数をカウントする、マップをバイパスする最も生産的な方法

8. Jsonと連携するためのライブラリ(Gson、Fastjson、LoganSquare、Jackson、JsonPathなど)





Java 8でストリームオブジェクトを作成することから始めましょう。



I.ストリームを作成する方法



ストリームを作成するいくつかの方法を次に示します。

ストリームを作成する方法 作成テンプレート
1.クラシック:コレクションからストリームを作成する コレクション。 ストリーム ()
 Collection<String> collection = Arrays.asList("a1", "a2", "a3"); Stream<String> streamFromCollection = collection.stream();
      
      



2.値のストリームを作成する Stream.ofvalue1 、... valueN
 Stream<String> streamFromValues = Stream.of("a1", "a2", "a3");
      
      



3.配列からストリームを作成する Arrays.stream配列
 String[] array = {"a1","a2","a3"}; Stream<String> streamFromArrays = Arrays.stream(array);
      
      



4.ファイルからストリームを作成します(ファイルの各行は、ストリームの個別の要素になります) Files.linesファイルへのパス
 Stream<String> streamFromFiles = Files.lines(Paths.get("file.txt"))
      
      



5.文字列からストリームを作成する 「ストリング」。 文字 ()
 IntStream streamFromString = "123".chars()
      
      



6. Stream.builderを使用する ストリーム ビルダー ()。 追加 (...).... ビルド ()
 Stream.builder().add("a1").add("a2").add("a3").build()
      
      



7.並列ストリームの作成 コレクション。 parallelStream ()
 Stream<String> stream = collection.parallelStream();
      
      





8. Stream.iterateを使用して無限のストリームを作成する

Stream.iteratestart_condition、generation_expression
 Stream<Integer> streamFromIterate = Stream.iterate(1, n -> n + 1)
      
      



9. Stream.generateを使用して無限ストリームを作成します Stream.generategeneration_expression
 Stream<String> streamFromGenerate = Stream.generate(() -> "a1")
      
      





原則として、ストリームを作成する最後の2つの方法に加えて、すべてがコレクションを作成する通常の方法と変わりません。 最後の2つのメソッドは、無限のストリームを生成するために機能します。初期条件が設定され、前の値から次の値を受け取る式、つまりStream.iterate(1、n-> n + 1)は値1、2、3、4、... Nを返しますStream.generateは定数値とランダム値を生成します。式に対応する値を返すだけです。この例では、無数の「a1」値を生成します。

ラムダを知らない人のために
式n-> n + 1は、式Integer func(Integer n){return n + 1;}の単なる類似物であり、式()-> "a1"は、式String func(){return "a1";}の類似物です。匿名クラス。



より詳細な例
また、この例はgithub 'eにあります。

  System.out.println("Test buildStream start"); //     Stream<String> streamFromValues = Stream.of("a1", "a2", "a3"); System.out.println("streamFromValues = " + streamFromValues.collect(Collectors.toList())); //  streamFromValues = [a1, a2, a3] //     String[] array = {"a1","a2","a3"}; Stream<String> streamFromArrays = Arrays.stream(array); System.out.println("streamFromArrays = " + streamFromArrays.collect(Collectors.toList())); //  streamFromArrays = [a1, a2, a3] Stream<String> streamFromArrays1 = Stream.of(array); System.out.println("streamFromArrays1 = " + streamFromArrays1.collect(Collectors.toList())); //  streamFromArrays = [a1, a2, a3] //     (        ) File file = new File("1.tmp"); file.deleteOnExit(); PrintWriter out = new PrintWriter(file); out.println("a1"); out.println("a2"); out.println("a3"); out.close(); Stream<String> streamFromFiles = Files.lines(Paths.get(file.getAbsolutePath())); System.out.println("streamFromFiles = " + streamFromFiles.collect(Collectors.toList())); //  streamFromFiles = [a1, a2, a3] //     Collection<String> collection = Arrays.asList("a1", "a2", "a3"); Stream<String> streamFromCollection = collection.stream(); System.out.println("streamFromCollection = " + streamFromCollection.collect(Collectors.toList())); //  streamFromCollection = [a1, a2, a3] //      IntStream streamFromString = "123".chars(); System.out.print("streamFromString = "); streamFromString.forEach((e)->System.out.print(e + " , ")); //  streamFromString = 49 , 50 , 51 , System.out.println(); //   Stream.builder Stream.Builder<String> builder = Stream.builder(); Stream<String> streamFromBuilder = builder.add("a1").add("a2").add("a3").build(); System.out.println("streamFromBuilder = " + streamFromBuilder.collect((Collectors.toList()))); //  streamFromFiles = [a1, a2, a3] //    //   Stream.iterate Stream<Integer> streamFromIterate = Stream.iterate(1, n -> n + 2); System.out.println("streamFromIterate = " + streamFromIterate.limit(3).collect(Collectors.toList())); //  streamFromIterate = [1, 3, 5] //   Stream.generate Stream<String> streamFromGenerate = Stream.generate(() -> "a1"); System.out.println("streamFromGenerate = " + streamFromGenerate.limit(3).collect(Collectors.toList())); //  streamFromGenerate = [a1, a1, a1] //    Stream<String> streamEmpty = Stream.empty(); System.out.println("streamEmpty = " + streamEmpty.collect(Collectors.toList())); //  streamEmpty = [] //      Stream<String> parallelStream = collection.parallelStream(); System.out.println("parallelStream = " + parallelStream.collect(Collectors.toList())); //  parallelStream = [a1, a2, a3]
      
      









II。 ストリーミング方法



Java Stream APIは、2種類のメソッドを提供します。

1.パイプライン-別のストリームを返します。つまり、ビルダーとして機能し、

2.ターミナル-コレクション、プリミティブ、オブジェクト、オプションなどの別のオブジェクトを返します。



パイプラインとターミナルメソッドの違い
一般的なルール :ストリームには任意の数のパイプラインコールと最後に1つのターミナルを含めることができますが、すべてのパイプラインメソッドは遅延して実行され、ターミナルメソッドが呼び出されるまで、スレッドまたはRunnableオブジェクトを作成するように実際にアクションは発生しませんただし、startを呼び出さないでください。



一般に、このメカニズムはSQLクエリの構築に似ており、ネストされたSelectはいくつあってもかまいませんが、結果は1つだけです。 たとえば、式collection.stream()。Filter((s)-> s.contains( "1"))。Skip(2).findFirst()、filterおよびskipはパイプライン処理され、findFirstはターミナルであり、オブジェクトを返します。オプションで、これでストリームの操作が終了します。





2.1ストリームを操作するためのパイプライン化されたメソッドの簡単な説明



ストリーム方式 説明
フィルター レコードをフィルタリングし、条件に一致するレコードのみを返します collection.stream()。filter( "a1" ::等しい).count()
飛ばす N個の最初の要素をスキップできます collection.stream()。skip(collection.size()-1).findFirst()。orElse( "1")
明確な 重複のないストリームを返します(equalsメソッドの場合) collection.stream()。distinct()。collect(Collectors.toList())
地図 各ストリーム項目を変換します collection.stream()。map((s)-> s + "_1")。collect(Collectors.toList())
のぞく 同じストリームを返しますが、ストリームの各要素に関数を適用します collection.stream()。map(String :: toUpperCase).peek((e)-> System.out.print( "、" + e))。

collect(Collectors.toList())
限界 選択を特定の数の最初の要素に制限できます。 collection.stream()。limit(2).collect(Collectors.toList())
ソート済み 自然な順序で、またはComparatorを設定して、値を並べ替えることができます collection.stream()。sort()。collect(Collectors.toList())
mapToInt

mapToDouble

mapToLong
mapに類似していますが、数値ストリーム(つまり、数値プリミティブのストリーム)を返します collection.stream()。mapToInt((s)-> Integer.parseInt(s))。toArray()
flatMap

flatMapToInt

flatMapToDouble

flatMapToLong
mapに似ていますが、1つの要素から複数を作成できます collection.stream()。flatMap((p)-> Arrays.asList(p.split( "、"))。stream())。toArray(String [] :: new)




2.2ストリームを操作する端末方法の簡単な説明



ストリーム方式 説明
findFirst ストリームの最初の要素を返します(オプションを返します) collection.stream()。findFirst()。orElse( "1")
findAny ストリームから適切なアイテムを返します(オプションを返します) collection.stream()。findAny()。orElse( "1")
集める コレクションおよびその他のデータ構造の形式での結果の表示 collection.stream()。filter((s)-> s.contains( "1"))。collect(Collectors.toList())
数える ストリーム内の要素の数を返します collection.stream()。filter( "a1" ::等しい).count()
anyMatch 少なくとも1つの要素について条件が満たされる場合、trueを返します collection.stream()。anyMatch( "a1" ::等しい)
なし一致 いずれかの要素について条件が満たされない場合、trueを返します collection.stream()。noneMatch( "a8" ::等しい)
allMatch すべての要素について条件が真の場合、真を返します collection.stream()。allMatch((s)-> s.contains( "1"))
コンパレーターを条件として使用して、最小要素を返します collection.stream()。min(String :: compareTo).get()
最大 コンパレーターを条件として使用して、最大要素を返します collection.stream()。max(String :: compareTo).get()
forEach 各ストリームオブジェクトに関数を適用します;並列実行での順序は保証されません set.stream()。forEach((p)-> p.append( "_ 1"));
forEachOrdered 各ストリームオブジェクトに関数を適用します;要素の順序を保持すると、 list.stream()。forEachOrdered((p)-> p.append( "_ new"));
toArray ストリーム値の配列を返します collection.stream()。map(String :: toUpperCase).toArray(String [] :: new);
減らす コレクション全体で集計関数を実行し、単一の結果を返すことができます collection.stream()。reduce((s1、s2)-> s1 + s2).orElse(0)


メソッドfindFirst、findAny、anyMatchは短絡メソッドに注意してください。つまり、ストリームのバイパスは、元のストリーム全体をバイパスせずに、適切な要素をできるだけ早く見つけるように編成されます。



2.3数値ストリームの追加メソッドの簡単な説明



ストリーム方式 説明
合計 すべての数値の合計を返します collection.stream()。mapToInt((s)-> Integer.parseInt(s))。sum()
平均的 すべての数値の算術平均を返します collection.stream()。mapToInt((s)-> Integer.parseInt(s))。average()
mapToObj 数値ストリームをオブジェクトストリームに変換します intStream.mapToObj((id)->新しいキー(id))。toArray()




2.4他のいくつかの便利なストリームメソッド



ストリーム方式 説明
isParallel ストリームが並列かどうかを調べる
平行 並列ストリームを返します。ストリームが既に並列である場合、それ自体を返すことができます
シーケンシャル 順次ストリームを返します。ストリームが既にシリアルである場合、それ自体を返すことができます


並列および順次メソッドを使用して、どの操作が並列になり、どの操作が順次のみになるかを判別できます。 また、シーケンシャルストリームからパラレルストリームを作成することもできます。

 collection.stream(). peek(...). //   parallel(). map(...). //    , sequential(). reduce(...) //   
      
      







:すべての並列ストリームは1つのフォーク/結合プールで動作し、そのような長い操作はJVMのすべての並列ストリームの動作を停止する可能性があるため、長時間の操作(データベース、ネットワーク接続からのデータの取得)に並列ストリームを使用しないことを強くお勧めしますプールに利用可能なスレッドがないため、つまり 並列ストリームは、ミリ秒単位でカウントが行われる短い操作にのみ使用する必要がありますが、秒単位および分単位でカウントが可能な操作には使用しないでください。



III。 ストリームメソッドの使用例



コレクションを操作するときに通常必要なさまざまなタスクのメソッドを操作することを検討してください。



3.1 filter、findFirst、findAny、skip、limit、countの使用例



条件 :Arrays.asList文字列のコレクション(「a1」、「a2」、「a3」、「a1」)が与えられた場合、filter、findFirst、findAny、skip、countメソッドを使用してどのように処理できるかを見てみましょう。

挑戦する サンプルコード 結果
オブジェクト「a1」の出現回数を返します collection.stream()。filter( "a1" ::等しい).count() 2
コレクションの最初の要素を返すか、コレクションが空の場合は0を返します collection.stream()。findFirst()。orElse( "0") a1
コレクションの最後のアイテムを返すか、コレクションが空の場合は「空」を返します collection.stream()。skip(collection.size()-1).findAny()。orElse( "empty") a1
「a3」に等しいコレクション内のアイテムを見つけるか、エラーをスローします collection.stream()。filter( "a3" :: equals).findFirst()。get() a3
コレクション内の3番目のアイテムを順番に返します collection.stream()。skip(2).findFirst()。get() a3
2番目から2つのアイテムを返します collection.stream()。skip(1).limit(2).toArray() [a2、a3]
テンプレートごとにすべてのアイテムを選択します。 collection.stream()。filter((s)-> s.contains( "1"))。collect(Collectors.toList()) [a1、a1]


findFirstおよびfindAnyメソッドは、NullPointerExceptionを回避するために、Java 8で導入された新しいOptional型を返すことに注意してください 。 フィルターメソッドは、特定の値セットのみを選択するために便利に使用され、スキップメソッドでは、特定の数の要素をスキップできます。

ラムダがわからない場合
式 "a3" :: equalsはブールfunc(s){return "a3" .equals(s);}の類似体であり、(s)-> s.contains( "1")はboolean func(s){return s.contains( "1");}は匿名クラスにラップされています。



条件 :コレクションがPeopleクラス(フィールド名-名前、年齢-年齢、性別-性別)、タイプArrays.asList(新しい人(「Vasya」、16、Sex.MAN)、新しい人(「Petya」、23、 Sex.MAN)、新しい人々( "Elena"、42、Sex.WOMEN)、新しい人々( "Ivan Ivanovich"、69、Sex.MAN))。 このクラスを操作する方法の例を見てみましょう。



挑戦する サンプルコード 結果
兵役の責任者を選択してください(18歳から27歳まで) peoples.stream()。filter((p)-> p.getAge()> = 18 && p.getAge()<27

&& p.getSex()== Sex.MAN).collect(Collectors.toList())
[{name = 'Petya'、年齢= 23、性別= MAN}]
男性の平均年齢を見つける peoples.stream()。filter((p)-> p.getSex()== Sex.MAN)。

mapToInt(People :: getAge).average()。getAsDouble()
36.0
サンプル内の潜在的に健常な人の数を見つけます(つまり、18歳から、女性は55歳、男性は60歳であることを考慮して) peoples.stream()。filter((p)-> p.getAge()> = 18).filter(

(p)->(p.getSex()== Sex.WOMEN && p.getAge()<55)|| (p.getSex()== Sex.MAN && p.getAge()<60))。count()
2


詳細な例
また、この例はgithub'eにあります。 ファーストクラスセカンドクラス

  // filter -  stream,     ,    // count -      // collect -  stream       // mapToInt -      (,  ) private static void testFilterAndCount() { System.out.println(); System.out.println("Test filter and count start"); Collection<String> collection = Arrays.asList("a1", "a2", "a3", "a1"); Collection<People> peoples = Arrays.asList( new People("", 16, Sex.MAN), new People("", 23, Sex.MAN), new People("", 42, Sex.WOMEN), new People(" ", 69, Sex.MAN) ); //     long count = collection.stream().filter("a1"::equals).count(); System.out.println("count = " + count); //  count = 2 //      List<String> select = collection.stream().filter((s) -> s.contains("1")).collect(Collectors.toList()); System.out.println("select = " + select); //  select = [a1, a1] //  - List<People> militaryService = peoples.stream().filter((p)-> p.getAge() >= 18 && p.getAge() < 27 && p.getSex() == Sex.MAN).collect(Collectors.toList()); System.out.println("militaryService = " + militaryService); //  militaryService = [{name='', age=23, sex=MAN}] //      double manAverageAge = peoples.stream().filter((p) -> p.getSex() == Sex.MAN). mapToInt(People::getAge).average().getAsDouble(); System.out.println("manAverageAge = " + manAverageAge); //  manAverageAge = 36.0 //  -      (..  18        55 ,    60) long peopleHowCanWork = peoples.stream().filter((p) -> p.getAge() >= 18).filter( (p) -> (p.getSex() == Sex.WOMEN && p.getAge() < 55) || (p.getSex() == Sex.MAN && p.getAge() < 60)).count(); System.out.println("peopleHowCanWork = " + peopleHowCanWork); //  manAverageAge = 2 } // findFirst -   Optional    // skip -  N   ( N  ) // collect  stream       private static void testFindFirstSkipCount() { Collection<String> collection = Arrays.asList("a1", "a2", "a3", "a1"); System.out.println("Test findFirst and skip start"); //     String first = collection.stream().findFirst().orElse("1"); System.out.println("first = " + first); //  first = a1 //     String last = collection.stream().skip(collection.size() - 1).findAny().orElse("1"); System.out.println("last = " + last ); //  last = a1 //     String find = collection.stream().filter("a3"::equals).findFirst().get(); System.out.println("find = " + find); //  find = a3 //       String third = collection.stream().skip(2).findFirst().get(); System.out.println("third = " + third); //  third = a3 System.out.println(); System.out.println("Test collect start"); //      List<String> select = collection.stream().filter((s) -> s.contains("1")).collect(Collectors.toList()); System.out.println("select = " + select); //  select = [a1, a1] } //  Limit        private static void testLimit() { System.out.println(); System.out.println("Test limit start"); Collection<String> collection = Arrays.asList("a1", "a2", "a3", "a1"); //     List<String> limit = collection.stream().limit(2).collect(Collectors.toList()); System.out.println("limit = " + limit); //  limit = [a1, a2] //       List<String> fromTo = collection.stream().skip(1).limit(2).collect(Collectors.toList()); System.out.println("fromTo = " + fromTo); //  fromTo = [a2, a3] //     String last = collection.stream().skip(collection.size() - 1).findAny().orElse("1"); System.out.println("last = " + last ); //  last = a1 } private enum Sex { MAN, WOMEN } private static class People { private final String name; private final Integer age; private final Sex sex; public People(String name, Integer age, Sex sex) { this.name = name; this.age = age; this.sex = sex; } public String getName() { return name; } public Integer getAge() { return age; } public Sex getSex() { return sex; } @Override public String toString() { return "{" + "name='" + name + '\'' + ", age=" + age + ", sex=" + sex + '}'; } }
      
      









3.2 distinctの使用例



distinctメソッドは重複なしでストリームを返しますが、順序付きストリーム(リストベースのコレクションなど)の場合、順序は安定しています。順序なしストリームの場合、順序は保証されません。 コレクションCollection Order = Arrays.asList(「a1」、「a2」、「a2」、「a3」、「a1」、「a2」、「a2」)およびCollection nonOrdered = new HashSet <>(ordered )

挑戦する サンプルコード 結果
順不同ストリームから重複のないコレクションを取得する nonOrdered.stream()。distinct()。collect(Collectors.toList()) [a1、a2、a3]-

順序は保証されません
順序付けされたストリームから重複のないコレクションを取得する ordered.stream()。distinct()。collect(Collectors.toList()); [a1、a2、a3]-

注文保証




注意してください:

1. equalsが再定義されたクラスでdistinctを使用する場合、equals / hashCodeコントラクト(最も重要なことは、すべてのequalsオブジェクトのhashCodeが同じ値を返すこと)に従ってhashCodeを正しく再定義することも必要です。 HashSet / HashMapを使用するときのように)、

2.並列ストリームを使用し、重複を削除した後、要素の順序を気にしない場合、並列ストリームでソートの安定性を維持するのは非常に高価なので、最初に順序なし()を使用してストリームを無秩序にし、次に別個の()を使用する方がパフォーマンスがはるかに優れています順序付けされたストリームのリソースと個別の()は、順序付けされていないストリームよりも完了するのにはるかに時間がかかります。



詳細な例
また、この例はgithub'eにあります

 //  distinct  stream  ,      (,    list)   ,   -    //  collect  stream       private static void testDistinct() { System.out.println(); System.out.println("Test distinct start"); Collection<String> ordered = Arrays.asList("a1", "a2", "a2", "a3", "a1", "a2", "a2"); Collection<String> nonOrdered = new HashSet<>(ordered); //     List<String> distinct = nonOrdered.stream().distinct().collect(Collectors.toList()); System.out.println("distinct = " + distinct); //  distinct = [a1, a2, a3] -    List<String> distinctOrdered = ordered.stream().distinct().collect(Collectors.toList()); System.out.println("distinctOrdered = " + distinctOrdered); //  distinct = [a1, a2, a3] -   }
      
      









3.3一致関数の使用例(anyMatch、allMatch、noneMatch)



条件 :Arrays.asList文字列のコレクション(「a1」、「a2」、「a3」、「a1」)が与えられた場合、Match関数を使用してどのように処理できるかを見てみましょう



挑戦する サンプルコード 結果
コレクションに少なくとも1つの「a1」アイテムが存在するかどうかを確認します。 collection.stream()。anyMatch( "a1" ::等しい) 本当
コレクションに少なくとも1つの「a8」要素が存在するかどうかを調べます collection.stream()。anyMatch( "a8" ::等しい)
コレクションのすべての要素に記号「1」があるかどうかを調べます collection.stream()。allMatch((s)-> s.contains( "1"))
コレクションに「a7」アイテムが存在しないことを確認します。 collection.stream()。noneMatch( "a7" ::等しい) 本当


詳細な例
また、この例はgithub'eにあります

  //  anyMatch -  true,         //  noneMatch -  true,         //  allMatch -  true,       private static void testMatch() { System.out.println(); System.out.println("Test anyMatch, allMatch, noneMatch start"); Collection<String> collection = Arrays.asList("a1", "a2", "a3", "a1"); //           boolean isAnyOneTrue = collection.stream().anyMatch("a1"::equals); System.out.println("anyOneTrue " + isAnyOneTrue); //  true boolean isAnyOneFalse = collection.stream().anyMatch("a8"::equals); System.out.println("anyOneFlase " + isAnyOneFalse); //  false //          boolean isAll = collection.stream().allMatch((s) -> s.contains("1")); System.out.println("isAll " + isAll); //  false //    boolean isNotEquals = collection.stream().noneMatch("a7"::equals); System.out.println("isNotEquals " + isNotEquals); //  true }
      
      









3.4 Map (map, mapToInt, FlatMap, FlatMapToInt)



: collection1 = Arrays.asList(«a1», «a2», «a3», «a1») collection2 = Arrays.asList(«1,2,0», «4,5»), map



挑戦する 結果
"_1" collection1.stream().map((s) -> s + "_1").collect(Collectors.toList()) [a1_1, a2_1, a3_1, a1_1]
(int[]) collection1.stream().mapToInt((s) -> Integer.parseInt(s.substring(1))).toArray() [1, 2, 3, 1]
, collection2.stream().flatMap((p) -> Arrays.asList(p.split(",")).stream()).toArray(String[]::new) [1, 2, 0, 4, 5]
, collection2.stream().flatMapToInt((p) -> Arrays.asList(p.split(",")).stream().mapToInt(Integer::parseInt)).sum() 12


: map (), map , Stream Integer People, Office, .., flatMap (flatMapToInt ..) , (. ).



また、この例はgithub'eにあります

  //  Map     ,  stream    private static void testMap() { System.out.println(); System.out.println("Test map start"); Collection<String> collection = Arrays.asList("a1", "a2", "a3", "a1"); //     List<String> transform = collection.stream().map((s) -> s + "_1").collect(Collectors.toList()); System.out.println("transform = " + transform); //  transform = [a1_1, a2_1, a3_1, a1_1] //       List<Integer> number = collection.stream().map((s) -> Integer.parseInt(s.substring(1))).collect(Collectors.toList()); System.out.println("number = " + number); //  transform = [1, 2, 3, 1] } //  MapToInt -     ,  stream     private static void testMapToInt() { System.out.println(); System.out.println("Test mapToInt start"); Collection<String> collection = Arrays.asList("a1", "a2", "a3", "a1"); //       int[] number = collection.stream().mapToInt((s) -> Integer.parseInt(s.substring(1))).toArray(); System.out.println("number = " + Arrays.toString(number)); //  number = [1, 2, 3, 1] } //  FlatMap -   Map -    ,    stream  private static void testFlatMap() { System.out.println(); System.out.println("Test flat map start"); Collection<String> collection = Arrays.asList("1,2,0", "4,5"); //    ,      collection String[] number = collection.stream().flatMap((p) -> Arrays.asList(p.split(",")).stream()).toArray(String[]::new); System.out.println("number = " + Arrays.toString(number)); //  number = [1, 2, 0, 4, 5] } //  FlatMapToInt -   MapToInt -    ,    stream  private static void testFlatMapToInt() { System.out.println(); System.out.println("Test flat map start"); Collection<String> collection = Arrays.asList("1,2,0", "4,5"); //     ,      collection int sum = collection.stream().flatMapToInt((p) -> Arrays.asList(p.split(",")).stream().mapToInt(Integer::parseInt)).sum(); System.out.println("sum = " + sum); //  sum = 12 }
      
      









3.5 Sorted



: Arrays.asList(«a1», «a4», «a3», «a2», «a1», «a4») People ( name — , age — , sex — ), Arrays.asList( new People(«», 16, Sex.MAN), new People(«», 23, Sex.MAN), new People(«», 42, Sex.WOMEN), new People(« », 69, Sex.MAN)). :



挑戦する 結果
collection.stream().sorted().collect(Collectors.toList()) [a1, a1, a2, a3, a4, a4]
collection.stream().sorted((o1, o2) -> -o1.compareTo(o2)).collect(Collectors.toList()) [a4, a4, a3, a2, a1, a1]
collection.stream().sorted().distinct().collect(Collectors.toList()) [a1, a2, a3, a4]
collection.stream().sorted((o1, o2) -> -o1.compareTo(o2)).distinct().collect(Collectors.toList()) [a4, a3, a2, a1]
peoples.stream().sorted((o1,o2) -> -o1.getName().compareTo(o2.getName())).collect(Collectors.toList()) [{''}, {' '}, {''}, {''}]

, peoples.stream().sorted((o1, o2) -> o1.getSex() != o2.getSex()? o1.getSex().

compareTo(o2.getSex()): o1.getAge().compareTo(o2.getAge())).collect(Collectors.toList())
[{''}, {''}, {' '}, {''}]




また、この例はgithub'eにあります

  //  Sorted       ,   Comparator private static void testSorted() { System.out.println(); System.out.println("Test sorted start"); // ************    Collection<String> collection = Arrays.asList("a1", "a4", "a3", "a2", "a1", "a4"); //     List<String> sorted = collection.stream().sorted().collect(Collectors.toList()); System.out.println("sorted = " + sorted); //  sorted = [a1, a1, a2, a3, a4, a4] //        List<String> sortedDistinct = collection.stream().sorted().distinct().collect(Collectors.toList()); System.out.println("sortedDistinct = " + sortedDistinct); //  sortedDistinct = [a1, a2, a3, a4] //        List<String> sortedReverse = collection.stream().sorted((o1, o2) -> -o1.compareTo(o2)).collect(Collectors.toList()); System.out.println("sortedReverse = " + sortedReverse); //  sortedReverse = [a4, a4, a3, a2, a1, a1] //           List<String> distinctReverse = collection.stream().sorted((o1, o2) -> -o1.compareTo(o2)).distinct().collect(Collectors.toList()); System.out.println("distinctReverse = " + distinctReverse); //  sortedReverse = [a4, a3, a2, a1] // ************    //    Collection<People> peoples = Arrays.asList( new People("", 16, Sex.MAN), new People("", 23, Sex.MAN), new People("", 42, Sex.WOMEN), new People(" ", 69, Sex.MAN) ); //        Collection<People> byName = peoples.stream().sorted((o1,o2) -> -o1.getName().compareTo(o2.getName())).collect(Collectors.toList()); System.out.println("byName = " + byName); // byName = [{name='', age=23, sex=MAN}, {name=' ', age=69, sex=MAN}, {name='', age=42, sex=WOMEN}, {name='', age=16, sex=MAN}] //    ,     Collection<People> bySexAndAge = peoples.stream().sorted((o1, o2) -> o1.getSex() != o2.getSex() ? o1.getSex(). compareTo(o2.getSex()) : o1.getAge().compareTo(o2.getAge())).collect(Collectors.toList()); System.out.println("bySexAndAge = " + bySexAndAge); // bySexAndAge = [{name='', age=16, sex=MAN}, {name='', age=23, sex=MAN}, {name=' ', age=69, sex=MAN}, {name='', age=42, sex=WOMEN}] } private enum Sex { MAN, WOMEN } private static class People { private final String name; private final Integer age; private final Sex sex; public People(String name, Integer age, Sex sex) { this.name = name; this.age = age; this.sex = sex; } public String getName() { return name; } public Integer getAge() { return age; } public Sex getSex() { return sex; } @Override public String toString() { return "{" + "name='" + name + '\'' + ", age=" + age + ", sex=" + sex + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof People)) return false; People people = (People) o; return Objects.equals(name, people.name) && Objects.equals(age, people.age) && Objects.equals(sex, people.sex); } @Override public int hashCode() { return Objects.hash(name, age, sex); } }
      
      









3.6 Max Min



: Arrays.asList(«a1», «a2», «a3», «a1»), Peoples Sorted Filter .



挑戦する 結果
collection.stream().max(String::compareTo).get() a3
collection.stream().min(String::compareTo).get() a1
peoples.stream().max((p1, p2) -> p1.getAge().compareTo(p2.getAge())).get() {name=' ', age=69, sex=MAN}
peoples.stream().min((p1, p2) -> p1.getAge().compareTo(p2.getAge())).get() {name='', age=16, sex=MAN}




また、この例はgithub'eにあります

  //  max   ,      //  min   ,      private static void testMinMax() { System.out.println(); System.out.println("Test min and max start"); // ************    Collection<String> collection = Arrays.asList("a1", "a2", "a3", "a1"); //    String max = collection.stream().max(String::compareTo).get(); System.out.println("max " + max); //  a3 //    String min = collection.stream().min(String::compareTo).get(); System.out.println("min " + min); //  a1 // ************     //    Collection<People> peoples = Arrays.asList( new People("", 16, Sex.MAN), new People("", 23, Sex.MAN), new People("", 42, Sex.WOMEN), new People(" ", 69, Sex.MAN) ); //      People older = peoples.stream().max((p1, p2) -> p1.getAge().compareTo(p2.getAge())).get(); System.out.println("older " + older); //  {name=' ', age=69, sex=MAN} //      People younger = peoples.stream().min((p1, p2) -> p1.getAge().compareTo(p2.getAge())).get(); System.out.println("younger " + younger); //  {name='', age=16, sex=MAN} } private enum Sex { MAN, WOMEN } private static class People { private final String name; private final Integer age; private final Sex sex; public People(String name, Integer age, Sex sex) { this.name = name; this.age = age; this.sex = sex; } public String getName() { return name; } public Integer getAge() { return age; } public Sex getSex() { return sex; } @Override public String toString() { return "{" + "name='" + name + '\'' + ", age=" + age + ", sex=" + sex + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof People)) return false; People people = (People) o; return Objects.equals(name, people.name) && Objects.equals(age, people.age) && Objects.equals(sex, people.sex); } @Override public int hashCode() { return Objects.hash(name, age, sex); } }
      
      









3.7 ForEach Peek



ForEach Peek , , ForEach , Peek . , :
  Collection<StringBuilder> list = Arrays.asList(new StringBuilder("a1"), new StringBuilder("a2"), new StringBuilder("a3"));
      
      





"_new", ForEach

  list.stream().forEachOrdered((p) -> p.append("_new")); // list -  [a1_new, a2_new, a3_new]
      
      





peek

  List<StringBuilder> newList = list.stream().peek((p) -> p.append("_new")).collect(Collectors.toList()); //  list  newList  [a1_new, a2_new, a3_new]
      
      







また、この例はgithub'eにあります

  //  ForEach             private static void testForEach() { System.out.println(); System.out.println("For each start"); Collection<String> collection = Arrays.asList("a1", "a2", "a3", "a1"); //        System.out.print("forEach = "); collection.stream().map(String::toUpperCase).forEach((e) -> System.out.print(e + ",")); //  forEach = A1,A2,A3,A1, System.out.println(); Collection<StringBuilder> list = Arrays.asList(new StringBuilder("a1"), new StringBuilder("a2"), new StringBuilder("a3")); list.stream().forEachOrdered((p) -> p.append("_new")); System.out.println("forEachOrdered = " + list); //  forEachOrdered = [a1_new, a2_new, a3_new] } //  Peek    ,           private static void testPeek() { System.out.println(); System.out.println("Test peek start"); Collection<String> collection = Arrays.asList("a1", "a2", "a3", "a1"); //        System.out.print("peak1 = "); List<String> peek = collection.stream().map(String::toUpperCase).peek((e) -> System.out.print(e + ",")). collect(Collectors.toList()); System.out.println(); //  peak1 = A1,A2,A3,A1, System.out.println("peek2 = " + peek); //  peek2 = [A1, A2, A3, A1] Collection<StringBuilder> list = Arrays.asList(new StringBuilder("a1"), new StringBuilder("a2"), new StringBuilder("a3")); List<StringBuilder> newList = list.stream().peek((p) -> p.append("_new")).collect(Collectors.toList()); System.out.println("newList = " + newList); //  newList = [a1_new, a2_new, a3_new] }
      
      









3.8 Reduce



reduce ( , ..), , — .



: Arrays.asList(1, 2, 3, 4, 2) reduce.



挑戦する 結果
0 collection.stream().reduce((s1, s2) -> s1 + s2).orElse(0) 12
-1 collection.stream().reduce(Integer::max).orElse(-1) 4
0 collection.stream().filter(o -> o % 2 != 0).reduce((s1, s2) -> s1 + s2).orElse(0) 4




また、この例はgithub'eにあります

  //  reduce        (  ,       ..) //    Optional  // map -      (,     ) // mapToInt -      (,    int) private static void testReduce() { System.out.println(); System.out.println("Test reduce start"); // ************     Collection<Integer> collection = Arrays.asList(1, 2, 3, 4, 2); //   Integer sum = collection.stream().reduce((s1, s2) -> s1 + s2).orElse(0); //  stream Api Integer sumOld = 0; //    for(Integer i: collection) { sumOld += i; } System.out.println("sum = " + sum + " : " + sumOld); //  sum = 12 : 12 //   Integer max1 = collection.stream().reduce((s1, s2) -> s1 > s2 ? s1 : s2).orElse(0); //  stream Api Integer max2 = collection.stream().reduce(Integer::max).orElse(0); //  stream Api  Integer::max Integer maxOld = null; //    for(Integer i: collection) { maxOld = maxOld != null && maxOld > i? maxOld: i; } maxOld = maxOld == null? 0 : maxOld; System.out.println("max = " + max1 + " : " + max2 + " : " + maxOld); //  max1 = 4 : 4 : 4 //   Integer min = collection.stream().reduce((s1, s2) -> s1 < s2 ? s1 : s2).orElse(0); //  stream Api Integer minOld = null; //    for(Integer i: collection) { minOld = minOld != null && minOld < i? minOld: i; } minOld = minOld == null? 0 : minOld; System.out.println("min = " + min+ " : " + minOld); //  min = 1 : 1 //    Integer last = collection.stream().reduce((s1, s2) -> s2).orElse(0); //  stream Api Integer lastOld = null; //    for(Integer i: collection) { lastOld = i; } lastOld = lastOld == null? 0 : lastOld; System.out.println("last = " + last + " : " + lastOld); //  last = 2 : 2 //   ,   2 Integer sumMore2 = collection.stream().filter(o -> o > 2).reduce((s1, s2) -> s1 + s2).orElse(0); //  stream Api Integer sumMore2Old = 0; //    for(Integer i: collection) { if(i > 2) { sumMore2Old += i; } } System.out.println("sumMore2 = " + sumMore2 + " : " + sumMore2Old); //  sumMore2 = 7 : 7 //     Integer sumOdd = collection.stream().filter(o -> o % 2 != 0).reduce((s1, s2) -> s1 + s2).orElse(0); //  stream Api Integer sumOddOld = 0; //    for(Integer i: collection) { if(i % 2 != 0) { sumOddOld += i; } } System.out.println("sumOdd = " + sumOdd + " : " + sumOddOld); //  sumOdd = 4 : 4 // ************     //    Collection<People> peoples = Arrays.asList( new People("", 16, Sex.MAN), new People("", 23, Sex.MAN), new People("", 42, Sex.WOMEN), new People(" ", 69, Sex.MAN) ); //     int oldMan = peoples.stream().filter((p) -> p.getSex() == Sex.MAN).map(People::getAge).reduce((s1, s2) -> s1 > s2 ? s1 : s2).get(); System.out.println("oldMan = " + oldMan); //  69 //             int younger = peoples.stream().filter((p) -> p.getName().contains("")).mapToInt(People::getAge).reduce((s1, s2) -> s1 < s2 ? s1 : s2).orElse(0); System.out.println("younger = " + younger); //  23 } private enum Sex { MAN, WOMEN } private static class People { private final String name; private final Integer age; private final Sex sex; public People(String name, Integer age, Sex sex) { this.name = name; this.age = age; this.sex = sex; } public String getName() { return name; } public Integer getAge() { return age; } public Sex getSex() { return sex; } @Override public String toString() { return "{" + "name='" + name + '\'' + ", age=" + age + ", sex=" + sex + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof People)) return false; People people = (People) o; return Objects.equals(name, people.name) && Objects.equals(age, people.age) && Objects.equals(sex, people.sex); } @Override public int hashCode() { return Objects.hash(name, age, sex); } }
      
      









3.9 toArray collect



toArray , toArray() Object[], toArray(T[]::new) — T, collect , map' . Collectors, List stream.collect(Collectors.toList()).



Collectors:

方法 説明
toList, toCollection, toSet ,
toConcurrentMap, toMap map
averagingInt, averagingDouble, averagingLong
summingInt, summingDouble, summingLong
summarizingInt, summarizingDouble, summarizingLong SummaryStatistics
partitioningBy Map<Boolean, List>
groupingBy Map<N, List<T>>
mapping Collector'




collect toArray :

: Arrays.asList(1, 2, 3, 4), collect toArray

挑戦する 結果
numbers.stream().collect(Collectors.summingInt(((p) -> p % 2 == 1? p: 0))) 4
1 numbers.stream().collect(Collectors.averagingInt((p) -> p — 1)) 1.5
3 numbers.stream().collect(Collectors.summarizingInt((p) -> p + 3)) IntSummaryStatistics{count=4, sum=22, min=4, average=5.5, max=7}
numbers.stream().collect(Collectors.partitioningBy((p) -> p % 2 == 0)) {false=[1, 3], true=[2, 4]}




: Arrays.asList(«a1», «b2», «c3», «a1»), collect toArray

挑戦する 結果
strings.stream().distinct().collect(Collectors.toList()) [a1, b2, c3]
strings.stream().distinct().map(String::toUpperCase).toArray(String[]::new) {A1, B2, C3}
: <b>… </b> strings.stream().collect(Collectors.joining(": ", "<b> ", " </b>")) <b> a1: b2: c3: a1 </b>
map, , strings.stream().distinct().collect(Collectors.toMap((p) -> p.substring(0, 1), (p) -> p.substring(1, 2))) {a=1, b=2, c=3}
map, strings.stream().collect(Collectors.groupingBy((p) -> p.substring(0, 1))) {a=[a1, a1], b=[b2], c=[c3]}
map, : strings.stream().collect(Collectors.groupingBy((p) -> p.substring(0, 1), Collectors.mapping((p) -> p.substring(1, 2), Collectors.joining(":")))) {a=1:1, b=2, c=3}




また、例はgithub'eにあります

  //  collect  stream       //     Collectors: // toList, toCollection, toSet -     ,    // toConcurrentMap, toMap -     map,    // averagingInt, averagingDouble, averagingLong -    // summingInt, summingDouble, summingLong -   // summarizingInt, summarizingDouble, summarizingLong -  SummaryStatistics     // partitioningBy -             Map<Boolean, List> // groupingBy -       Map<N, List<T>>,  T -   , N -   // mapping -      Collector' private static void testCollect() { System.out.println(); System.out.println("Test distinct start"); // ********    Collection<String> strings = Arrays.asList("a1", "b2", "c3", "a1"); //        List<String> distinct = strings.stream().distinct().collect(Collectors.toList()); System.out.println("distinct = " + distinct); //  distinct = [a1, b2, c3] //        String[] array = strings.stream().distinct().map(String::toUpperCase).toArray(String[]::new); System.out.println("array = " + Arrays.asList(array)); //  array = [A1, B2, C3] //         :    <b> ... </b> String join = strings.stream().collect(Collectors.joining(" : ", "<b> ", " </b>")); System.out.println("join = " + join); //  <b> a1 : b2 : c3 : a1 </b> //   map,    ,    Map<String, String> map = strings.stream().distinct().collect(Collectors.toMap((p) -> p.substring(0, 1), (p) -> p.substring(1, 2))); System.out.println("map = " + map); //  map = {a=1, b=2, c=3} //   map,      Map<String, List<String>> groups = strings.stream().collect(Collectors.groupingBy((p) -> p.substring(0, 1))); System.out.println("groups = " + groups); //  groups = {a=[a1, a1], b=[b2], c=[c3]} //   map,               : Map<String, String> groupJoin = strings.stream().collect(Collectors.groupingBy((p) -> p.substring(0, 1), Collectors.mapping((p) -> p.substring(1, 2), Collectors.joining(":")))); System.out.println("groupJoin = " + groupJoin); //  groupJoin = groupJoin = {a=1/1, b=2, c=3} // ********    Collection<Integer> numbers = Arrays.asList(1, 2, 3, 4); //     long sumOdd = numbers.stream().collect(Collectors.summingInt(((p) -> p % 2 == 1 ? p : 0))); System.out.println("sumOdd = " + sumOdd); //  sumEven = 4 //     1    double average = numbers.stream().collect(Collectors.averagingInt((p) -> p - 1)); System.out.println("average = " + average); //  average = 1.5 //    3    IntSummaryStatistics statistics = numbers.stream().collect(Collectors.summarizingInt((p) -> p + 3)); System.out.println("statistics = " + statistics); //  statistics = IntSummaryStatistics{count=4, sum=22, min=4, average=5.500000, max=7} //      IntSummaryStatistics long sumEven = numbers.stream().collect(Collectors.summarizingInt((p) -> p % 2 == 0 ? p : 0)).getSum(); System.out.println("sumEven = " + sumEven); //  sumEven = 6 //       Map<Boolean, List<Integer>> parts = numbers.stream().collect(Collectors.partitioningBy((p) -> p % 2 == 0)); System.out.println("parts = " + parts); //  parts = {false=[1, 3], true=[2, 4]} }
      
      









3.10 Collector'a



Collector' Collectors Collector, .



Collector'a:



 Collector<_, _, _> ollector = Collector.of( __, ___, ___, [___] );
      
      







, Collector'a (___ ). , Java 8, :



  StringBuilder b = new StringBuilder(); // __ for(String s: strings) { b.append(s).append(" , "); // ___, } String joinBuilderOld = b.toString(); // ___
      
      







, Java 8



 String joinBuilder = strings.stream().collect( Collector.of( StringBuilder::new, // __ (b ,s) -> b.append(s).append(" , "), // ___, (b1, b2) -> b1.append(b2).append(" , "), // ___ StringBuilder::toString // ___ ) );
      
      







-, , , ___? Collector'a, ( ), StringBuilder , Java 8 2 :



  StringBuilder b1 = new StringBuilder(); // ___1 for(String s: stringsPart1) { // stringsPart1 -    strings b1.append(s).append(" , "); // ___, } StringBuilder b2 = new StringBuilder(); // ___2 for(String s: stringsPart2) { // stringsPart2 -    strings b2.append(s).append(" , "); // ___, } StringBuilder b = b1.append(b2).append(" , "), // ___ String joinBuilderOld = b.toString(); // ___
      
      







Collectors.toList() :

  //    toList Collector<String, List<String>, List<String>> toList = Collector.of( ArrayList::new, //    List::add, //     (l1, l2) -> { l1.addAll(l2); return l1; } //        ); //           List<String> distinct1 = strings.stream().distinct().collect(toList);
      
      







githubでもサンプルを見つけることができます

  //   Collector,        StringBuilder Collector<String,StringBuilder, String> stringBuilderCollector = Collector.of( StringBuilder::new, //    (b ,s) -> b.append(s).append(" , "), //     (b1, b2) -> b1.append(b2).append(" , "), //        StringBuilder::toString // ,     ); String joinBuilder = strings.stream().collect(stringBuilderCollector); System.out.println("joinBuilder = " + joinBuilder); //  joinBuilder = a1 , b2 , c3 , a1 , //  Collector'   JDK7   StringBuilder b = new StringBuilder(); //    for(String s: strings) { b.append(s).append(" , "); //     } String joinBuilderOld = b.toString(); // ,     System.out.println("joinBuilderOld = " + joinBuilderOld); //  joinBuilderOld = a1 , b2 , c3 , a1 , //    toList         Collector<String, List<String>, List<String>> toList = Collector.of( ArrayList::new, //    List::add, //     (l1, l2) -> { l1.addAll(l2); return l1; } //        ); List<String> distinct1 = strings.stream().distinct().collect(toList); System.out.println("distinct1 = " + distinct1); //  distinct1 = [a1, b2, c3]
      
      







IV。 おわりに



以上です。 , stream api . github' , .



PS , Stream Api:

1. Processing Data with Java SE 8 Streams, Part 1 Oracle,

2. Processing Data with Java SE 8 Streams, Part 2 Oracle,

3. Java 8 Stream



PPS opensource useful-java-links — , Java , . opensource Hello world Java maven ( ).



''
1. JPA Hibernate

2. Java opensource github

3. Java (, guava, apache, trove, gs-collections

4. Java Stream API

5. Java

6. Java

7

7.1 InputStream

7.2 Map',

8. Json (Gson, Fastjson, LoganSquare, Jackson, JsonPath )




All Articles