1. ホーム
  2. java

[解決済み] Java 8: java.util.function の TriFunction (と kin) はどこにあるのでしょうか?または代替は何ですか?

2022-02-18 07:21:27

質問内容

java.util.function.BiFunctionを見ると、これができるんですね。

BiFunction<Integer, Integer, Integer> f = (x, y) -> { return 0; };

それではダメで、TriFunctionが必要だとしたらどうでしょう? それは存在しない!

TriFunction<Integer, Integer, Integer, Integer> f = (x, y, z) -> { return 0; };

私は、独自のTriFunctionを定義できることは知っていますが、それを標準ライブラリに含めないことの根拠を理解しようとしているのです。

どのように解決するのか?

私の知る限り、関数には破壊的なものと建設的なものの2種類しかありません。

建設的な関数は、その名の通り何かを建設するのに対して、破壊的な関数は何かを破壊するのですが、あなたが今考えているような方法ではありません。

例えば、関数

Function<Integer,Integer> f = (x,y) -> x + y  

構成的 の1つです。 何かを構築する必要があるように この例では というタプルを構築しました。 (x,y) . 構成的関数には問題があります。 無限の引数を処理することができないからです。しかし、最悪なのは 引数を空けることはできない。さて、x := 1" と言って、試しに あなたが試したいと思うすべてのy。というタプル全体を毎回構築しなければならない。 x := 1 . というわけで、関数が何を返すのか見たい場合は y := 1, y := 2, y := 3 あなた と書かなければなりません。 f(1,1) , f(1,2) , f(1,3) .

Java 8では、構成的ラムダ関数を使う利点があまりないため、構成的関数は(ほとんどの場合)メソッド参照を使って処理されるべきです。これは、静的メソッドに少し似ています。 使用することはできますが、実際の状態を持ちません。

もうひとつは破壊的なタイプで、何かを受け取って必要な範囲で解体します。 例えば 破壊的 機能

Function<Integer, Function<Integer, Integer>> g = x -> (y -> x + y) 

は、この関数と同じように f これは建設的なものです。破壊的な関数の利点は 無限大の引数を扱えるようになり、特にストリームでは便利です。 というわけで、もしもう一度 x := 1y := 1 , y := 2 , y := 3 と言うことができます。 h = g(1)h(1)y := 1 , h(2) について y := 2h(3) に対して y := 3 .

つまり、ここでは状態が固定されているのです! これは非常にダイナミックで、ラムダが必要とするのは大抵の場合これです。

Factoryのようなパターンは、自分のために仕事をしてくれる関数を置くことができれば、とても簡単です。

破壊的なもの同士は簡単に組み合わせられる。型が正しければ、好きなように合成すればいいのです。これを使えば、モルヒズムを簡単に定義できるので、(イミュータブルな値を使った)テストがとても簡単になりますよ。

破壊的な構成はリストやデコレータのようにきれいに見えますが、構成的なものはツリーによく似ています。そして、バックトラックのようなもの 構成的関数の場合は、ただ単に不愉快なだけです。破壊的な関数の部分関数を保存しておいて(動的計画法)、"backtrack" で古い破壊的な関数を使えばいいんです。そうすれば、コードはずっと小さくなり、読みやすくなります。構成的関数の場合、多かれ少なかれ、すべての引数を覚えておかなければなりませんが、それはとても大変なことです。

では、なぜ BiFunction がないことの方が問題でしょう。 TriFunction ?

まず、多くの場合、いくつかの値(3つ未満)があり、結果だけが必要です。したがって、通常の破壊的な関数はまったく必要なく、構成的な関数で十分です。また、モナドのようなものもあります。 は本当に構成的な関数が必要です。しかし、それを除けば、なぜ BiFunction ということです。だからといって、削除する必要はありません。私は死ぬまでモナドのために戦います!

ですから、論理的なコンテナ・クラスにまとめられないようなたくさんの引数がある場合、そして、その引数を使った 関数は建設的でなければならないので、メソッド参照を使用します。そうでなければ、破壊的な関数という新しく獲得した能力を使ってみてください、あなたはより少ないコード行数で多くのことを行っていることに気づくかもしれません。