ホームページ  >  記事  >  Java  >  Java8 での関数型プログラミングの例

Java8 での関数型プログラミングの例

黄舟
黄舟オリジナル
2017-08-09 14:03:281957ブラウズ

関数型プログラミング、この単語は関数とプログラミングという 2 つの名詞で構成されています。プログラミングという言葉を説明する必要はありません。誰もがやっていることです。実際、関数という言葉は切り離して考えると馴染みがありませんが、この 2 つの組み合わせは何でしょうか? 以下の記事では、Java8 関数型プログラミングに関する関連情報を紹介します。

はじめに

前の記事では、ラムダとストリームについて簡単に学びました。この章では、関数型プログラミングの考え方を確認して理解します。 関数型という用語が何度も出てきますが、それはラムダのことを指しているのでしょうか?もしそうなら、関数型プログラミングはあなたにどのような利点をもたらしますか? , たとえば、料理をするときは、通常、慣れ親しんだ調理方法に従って、まず野菜を洗い、次に野菜を切り、油を熱し、食器を置き、そして...これは一連の命令のように見えます。これを命令型プログラミングと呼びます。その特徴は、シリアル化され命令型である工場の組立ラインやコンピューターの命令処理によく似ています。

CookingTask cookingTask = new CookingTask();
cookingTask.wash();
cookingTask.cut();
cookingTask.deepFry();
cookingTask.fried();
...
宣言プログラミング

ラムダと関数式を使用して上記の問題を解決する場合、次のようになります:

public class CookingDemo {
 public void doTask(String material, Consumer<String> consumer) {
  consumer.accept(material);
 }
 public static void main(String[] args) {
  CookingDemo cookingDemo = new CookingDemo();
  cookingDemo.doTask("蔬菜", material -> System.out.println("清洗" + material));
  cookingDemo.doTask("蔬菜", material -> System.out.println(material + "切片"));
  cookingDemo.doTask("食用油", material -> System.out.println(material + "烧热"));
  cookingDemo.doTask("", material -> System.out.println("炒菜"));
 }
}

ここでクックします。実装の詳細は関数ライブラリに任せられます。このようにして、クッキング プロセスに他のステップを追加すると、その関数をすぐに理解できるようになります。 doTask メソッドを呼び出して処理する材料を渡すだけで済みます。たとえば、卵を処理するメソッドを記述することなく、食​​用油を加熱する前に卵を溶きたい


cookingDemo.doTask("鸡蛋", material -> System.out.println(material + "打碎搅拌均匀"));

関数型プログラミングとは

「関数型プログラミングとは何か」という質問に対する最も簡単な答えは、「関数を使用したプログラミングの方法です」です。 理解は人それぞれ異なりますが、核心は次のとおりです。問題を考えるときは、関数は不変の値と関数を使用して、ある値を処理し、それを別の値にマッピングします。


異なる言語コミュニティは、それぞれの言語の特徴に対して排他的な賞賛を抱いていることがよくあります。 Java プログラマが関数型プログラミングをどのように定義しているかについて話すのは時期尚早ですが、それはまったく問題ではありません。私たちは、関数型プログラミングのスタイルに準拠したコードではなく、優れたコードを書くことを重視しています。

文字列型とブール型のパラメータを入力し、整数のパラメータを出力する関数を設計することを想像してみましょう。

int pos = 0;
public Integer foo(String str, boolea flag){
 if(flag && null != str){
  pos++;
 }
 return pos;
}
この例には入力と出力があり、同時に各呼び出しで外部変数の値も更新される可能性があります。このような関数を副作用付き関数と呼びます。

関数型プログラミングのコンテキストでは、「関数」は数学関数に対応します。0 個以上の引数を受け取り、1 つ以上の結果を生成し、副作用はありません。 以下の関数のように、入力を受け取り、何らかの出力を生成するブラック ボックスと考えることができます

public Integer foo(String str, boolea flag){
 if(flag && null != str){
  return 1;
 }
 return 0;
}

このタイプの関数と Java プログラミング言語で見られる関数の違いは非常に重要です ( log や sin などの数学関数には副作用があることを想像してください)。 特に、数学関数が同じパラメータで呼び出された場合、返される結果は同じでなければなりません。ここでは、今のところ Random.nextInt のようなメソッドについては考慮しません。


関数の副作用

「関数型」について話すとき、私たちが言いたいのは、実際には「数学関数のような - 副作用がない」ということです。 。このことから、プログラミングにおけるいくつかの微妙な問題が発生します。 すべての関数は関数と if-then-else のような数学的考え方を使用してのみ構築できるということですか? それとも、これらの操作の結果がシステムの他の部分に公開されない限り、関数が非機能的な操作を内部で実行することも許可しますか? 言い換えれば、プログラムに特定の副作用があるが、その副作用が他の呼び出し元には認識されない場合、その副作用は存在しないと仮定できますか? 呼び出し元は、これらの副作用についてはまったく影響を及ぼさないため、知る必要も気にする必要もありません。


この 2 つの違いを定義したい場合、前者を純粋関数型プログラミングと呼び、後者を関数型プログラミングと呼びます。

実際のプログラミングでは、標準ライブラリ関数を含む多くの古いコードには副作用があるため、Java 言語を使用して純粋に関数的な方法でプログラムを完成させることは困難です (Scanner.nextLine の呼び出しには副作用があり、最初から始まります)。 a ファイルから 1 行を読み取ります。通常、2 つの呼び出しの結果は完全に異なります)。システムのほぼ純粋に機能的な実装を作成したいと考えており、コードに副作用がないことを確認する必要があります。このような関数またはメソッドには副作用がないと仮定します。実行のためにメソッド本体に入るとき、フィールドの値は 1 ずつ増加し、メソッド本体を終了する前に、フィールドの値は 1 ずつ減少します。シングルスレッド プログラムの場合、このメソッドには副作用がなく、機能実装とみなすことができます。

関数型スタイルを構築するためのガイドラインは、「関数型スタイル」と呼ばれる関数またはメソッドはローカル変数のみを変更できるということです。また、それが参照するオブジェクトは Final である必要があります。 すべての参照型フィールドは不変オブジェクトを指します。

概要

以上がJava8 での関数型プログラミングの例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。