JavaRush /Java Blog /Random-JA /単純ではない単純なフロー
Oleg Savenko
レベル 41
Одесса

単純ではない単純なフロー

Random-JA グループに公開済み
Java のバージョンが新しくなるたびに、Java はますます充実していきます。豊富な機能の多くは以前のバージョンにありますが、この言語は方法論と実装の両方で改善され続けています。Java のコレクションも例外ではありません。 コア コレクション フレームワークは J2SE 1.2 で登場してから進化を続け、失望するというよりはむしろ喜ばしい変化を経験しました。JDK 5 のリリースにより、コレクションはさらに便利、高速、そして簡単に操作できるようになりました。これにより、プログラマーがそれらをより集中的に悪用し始めたという事実が生じました。それらを扱うための特定のパターンが開発されており、間違いなく効果的です。しかし、JDK 8 ではコレクションが再び改善され、スレッドのおかげでさらに改善されました。明らかに、コレクションをストリームの形式で表現できるため、それらを操作する方法も変わります。したがって、コレクションを使用した馴染みのあるわかりやすいソリューションがどのようにさらにシンプルになるかを示したいと思います。

例 1. これ以上に簡単なことはありません

もちろん、最も単純なことから始めましょう。コレクションのすべての要素を調べて、すべての要素を表示してみましょう。
// создадим и заполним список
   List<Integer> list = new ArrayList<>();
   Collections.addAll(list, 1, 5, 6, 11, 3, 15, 7, 8);
   // а теперь
   // быстрый for по всем elementм, только для коллекций
   for (Integer i:list){
       System.out.println(i);
   }
   //но мы уже живем в JDK 8
   //а значит нужно так
   list.stream().forEach(System.out::println);
お気づきのとおり、Java 初心者の私の意見では、より単純な新しい構文があります。新しい構文では次のことがわかります。
берем_список(list).превращаем_в_поток(stream).перебираем_все_элементы(forEach)(тут_интуитивно_понятно)
System.out::println— 文字列をコンソールに出力する静的メソッドへのリンク 静的メソッドへのリンクの代わりに、少し異なる、あまり明確ではないエントリを使用できます。
list.stream().forEach(i -> System.out.println(i));
このエントリではラムダ式を使用します。はい、ストリームの操作方法を学ぶには、ラムダ式を学ぶ必要があります。ラムダ式は素晴らしいものです。さらに、コース中に従来の方法に慣れてきたという事実に基づいて、ストリームのみを使用してコレクションを操作する方法については説明しません。

例 2. リスト内の偶数の値を見つけてコンソールに表示する

list.stream().filter(i -> i%2==0).forEach(System.out::println);
問題全体は 1 行で解決されました。一行の仕事を楽しんでいただければ幸いです。このメソッドを使用して、filterストリームをフィルタリングし、残ったものをコンソールに出力しました。フィルターは、最も予期しないケースで役立つ非常に強力なものです。創造力を発揮して問題の条件を変えてみましょう。たとえば、リスト内に偶数がいくつあるかを数える必要があります。
long count = list.stream().filter(i -> i%2==0).count();
そしてまた一行で。どういうわけかすべてが単純に思えます。フィルターではラムダ式を使用して、新しいストリームに偶数のみを配置し、新しいストリームに適用してcount、新しいストリームに含まれる要素の数をカウントしました。

例 3. リスト内の 5 文字の長さの単語がいくつあるか数えてみましょう

整数を使って遊んできましたが、今度は単語を使ってみましょう。
List<String> list = new ArrayList<>();
Collections.addAll(list, "разые", "слова", "интересные", "And", "Not", "Very");

System.out.println(list.stream().filter(w -> w.length() == 5).count());
フィルターを再度使用しました。フィルターでは、ラムダ式を使用して新しいストリームが表示され、当然のことですが、count新しいストリームに含まれる要素の数を計算しました。

例 4. 固有の単語を出力する

多くの異なる単語をファイルからコレクションに読み込むときのおなじみの作業ですが、今後は一意の単語のみが必要になります。
List<String> list = new ArrayList<>();
Collections.addAll(list, "Vasya", "Таня", "Olya", "Vasya", "Olya", "Сергей");

list.stream().distinct().forEach(System.out::println);
主なアクションは、を使用してストリーム上で実行されましたdistinct。次に、スレッドを使用してコースのタスクのいくつかを見てみることをお勧めします。

例 5. 長い単語

Java Core の第 9 レベルの講義 11 には興味深い問題があります。この問題では、ファイル 2 にカンマで区切られた単語を記述する必要があります。その長さは厳密に 6 よりも大きくなければなりません。フェンスで囲っている庭の種類に関係なく、私は次の解決策を提案します。
  1. ソース ファイルからすべての単語をリストに読み込みます。

  2. 次に、次の行を実行します

    Optional<String> rezult = list.stream()
    				.filter(w->w.length()>6)
    				.reduce((w1,w2)->w1+", "+w2);
  3. result.get()ファイルに書き込みます。

ここではスレッドを使用した興味深い解決策を紹介します。フィルタがフィルタリングされ、reduce と正規表現を使用して、必要な文字列が生成されました。

例 6. 数字を含む単語

File2 には、a1 や abc3d など、数字を含むすべての単語をスペースで区切って書き込みます。これも問題集の条件ですが、ご想像のとおり、解決策は簡単です。
Optional<String> rezult = list.stream()
				.filter(w->w.matches(".*?\\d+.*?"))
				.reduce((w1,w2)->w1+" "+w2);
正規表現を使用してストリームをフィルタリングし、次に、reduce とラムダ式を使用しました。前のタスクと多くの共通点があります。

例 7. 数字の選択

タスク全体は次のようになります。
  • コンソールから 2 つのファイル名を読み取ります。
  • 最初のファイルにあるすべての数値を 2 番目のファイルに出力します。
  • 数字はスペースで区切られます。
  • ストリームを閉じます。
スペースで区切られた文字列に数値を書き込む主なタスクでは、さらにファイルに書き込むために、ストリームを使用することをお勧めします。次のようになります。
Optional<String> rezult = list.stream().filter(w->w.matches("\\d+"))
				.reduce((w1,w2)->w1+" "+w2);
System.out.println(rezult.get());
スレッドを使用すると、問題は非常に簡単な方法で解決されます。しかし、なんと、このソリューションを前の 2 つのソリューションと比較してみてください。記事の締めくくりとして、皆さんに告白したいと思います。私は例を選択したときに不正行為をしました。実際のところ、馴染みのある問題を使って馴染みのないトピックを紹介するために、最も単純な例を選択しました。もちろん、スレッドは単純なタスクとより複雑なタスクの両方に使用されます。しかし、ホーストマン氏が著書の中で強調したように、「データ フローは、「何を行うかではなく、何を行うか」という原則に基づいて動作します。」これは、これまで複雑だった多くのタスクがよりシンプルになる可能性があることを意味します。あなたはどうか知りませんが、私はフローが好きでした。あなたがフローを学ぶのを妨げなかったことを願っています。そして、もう一つ説明させてください。
  1. 私は読者にコレクション内でのストリームの使用方法を教えることを目的としたわけではありません。私はそれほど経験豊富な教師ではありません。スレッドはシンプルでありながら非常に興味深いものであることを示したかったのです。一般に、これは必需品です。
  2. フローを理解すればするほど、教科書の問題をすべて解決する問題が多くなります。これは、フローの発明が無駄ではなかったということを意味します。
  3. ストリームは操作が簡単なだけでなく、重要な利点もあります。大量のデータを操作する場合、多くの場合、ストリームの方が生産性が高くなります。
PS。私はすべての問題について冗談を言っていました。 推奨:プロフェッショナル Java ライブラリ。第 2 巻 高度なプログラミング ツール。ケイ・ホーストマン。私が持っているのは第10版です。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION